Search code examples
androidfile-transfersmack

File Transfer not working smack 4.1 android


Currently I am playing around with the new Smack 4.1 that offers full support for android. Sending and receiving messages is no problem, works fine. But now, I get stuck on sending and receiving Files. For example:

Send File

public void sendFile(String fileName,String to){

        if(transferManager==null) {
            transferManager = FileTransferManager.getInstanceFor(mConnection);

        }


        OutgoingFileTransfer transfer = transferManager.createOutgoingFileTransfer(to);

        try {

            transfer.sendFile(new File(fileName), "This is a Test!");
        } catch (SmackException e) {
            e.printStackTrace();
        }
    }

Receive files

 public void setReceiveFileListener(){


        if(transferManager==null) {
            transferManager = FileTransferManager.getInstanceFor(mConnection);
        }
        transferManager.addFileTransferListener(new FileTransferListener() {
            @Override
            public void fileTransferRequest(FileTransferRequest request) {
                IncomingFileTransfer transfer = request.accept();

                try {
                    File file = new File(Environment.getExternalStorageDirectory()  + File.separator +"TEST"+File.separator+ "new.txt");
                    transfer.recieveFile(file);

                } catch (SmackException | IOException e) {
                    e.printStackTrace();

                }
            }
        });

    }

In this scenario, I just send a text file and want to save it as a new text file at sd card as "new.txt". The problem is not with the file itself, the file exists. Also, the receiver id is correct, it´s like "user@host.com/Smack" . That´s the same receiver which I can send normal messages successfully.

The error code I get from Smack:

error 503 - service unavailable

This error respone I get directly from smack after sending file and it seems the file is not transferred, because the receiver listener shows nothing (I made Logs on both, sending and receiving), but listener is surely registerred. But I am totally sure, that File Transfer is supported by the server, it´s declared at their website www.coderollers.com . I´ve read many questions about here in SO and also at the Smack Developer Community. Nothing helped, so my question here is:

  1. What could be the cause of this problem?
  2. Could it be because I have to change the Port?
  3. How to change the port of an existing connection in smack?
  4. Any alternatives to file transport?

My normal port is 5222, that works fine to send messages. I hope someone get it work and can lead me to the right directions....thanks for helping!

SOLUTION

For all who are interested: Devendra Singhs answer is correct, with a little note by myself. It seems to be important, which resource is used. From mobile to mobile, You have to use "mobile". Wether "Smack" nor any other resource identifier would work here. So it is important to initialize the OutgoingFileTransfer correctly like this:

        OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer
(XmppStringUtils.completeJidFrom(USER, SERV, "mobile"));//important resource "mobile"

Solution

  • I got it after very research.

    FileTransferManager ftm1 = FileTransferManager.getInstanceFor(connection);
        FileTransferManager ftm2 = FileTransferManager.getInstanceFor(connection2);
    
        ftm2.addFileTransferListener(new FileTransferListener() {
            @Override
            public void fileTransferRequest(FileTransferRequest request) {
                IncomingFileTransfer ift = request.accept();
                try {
                    InputStream is = ift.recieveFile();
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    int nRead;
                    byte[] buf = new byte[1024];
                    while ((nRead = is.read(buf,  0, buf.length)) != -1) {
                        os.write(buf, 0, nRead);
                    }
                    os.flush();
                    dataReceived = os.toByteArray();
                } catch (SmackException | IOException | XMPPErrorException e) {
                    e.printStackTrace();
                }
                if (Arrays.equals(dataToSend, dataReceived)) {
                    System.out.println("Received data matches send data. \\o/");
                } else {
                    System.err.println("Recieved data DOES NOT match send data. :(");
                }
            }
        });
    
        OutgoingFileTransfer oft = ftm1.createOutgoingFileTransfer(XmppStringUtils.completeJidFrom(USER, SERV, "resourse"));
        oft.sendStream(new ByteArrayInputStream(dataToSend), "hello.txt", dataToSend.length, "A greeting");
        outerloop: while (!oft.isDone()) {
            switch (oft.getStatus()) {
            case error:
                System.out.println("Filetransfer error: " + oft.getError());
                break outerloop;
            default:
                System.out.println("Filetransfer status: " + oft.getStatus() + ". Progress: " + oft.getProgress());
                break;
            }
            Thread.sleep(1000);
        }
    
        connection.disconnect();
        connection2.disconnect();
        Thread.sleep(1000);
    }
    

    the one connection is sending file and another connection is receiving this is working code.