File transfer in android with asmack and Openfire

I have seen many peoples struggling from file transfer in asmackAndroid build environment and patches for smack. I tried same library with Openfire server after some debugging got success in it. So I will like to share my problem and solution for it.  I found that the problem is in Byte Stream host, it tries to connect to wrong host for initiating file transfer using byte streams.  If you have not configured the file transfer proxy properly then it will choose 127.0.0.1 or localhost or any internally configured host/ip as a bytestream host, which in android is not considered as proper ip for communicating.  But wait then why it is working properly with desktop client with same server. The reason is desktop clients can easily identify this ips and can use it to open socket for file transfer.

The variable names used in following discussions are:

Name Meaning
myHost The hostname of machine on which Openfire is running.
user1@myHost File transfer initiator user
user2@myHost Recipient of file

How to know which host is chosen for byte streams: (Following XMLs are shown as they are sent and received to the file transfer initiator.)

  • First query other client for information about supported features:

Sent:

<iq id="x1ixz-13" to="user2@myHost/Smack" type="get">
   <query xmlns="http://jabber.org/protocol/disco#info"></query>
</iq>

Received:

<iq id="x1ixz-13" to="user1@myHost/Smack" type="result" from="user2@myHost/Smack">
   <query xmlns="http://jabber.org/protocol/disco#info">
      <!—some other items -->
      <feature var="http://jabber.org/protocol/bytestreams"/>
      <!—some other items -->
   </query>
</iq>

Here you can know that whether bytestream file transfer is supported on the client other side or not. If you see a xml like above in response then it’s supported on the other side and you can go further.

  • Query server for disco items:

Sent:

<iq id="x1ixz-14" to="myHost" type="get">
   <query xmlns="http://jabber.org/protocol/disco#items"></query>
</iq>

Received:

<iq type="result" id="x1ixz-14" from="myHost" to="user1@ myHost /Smack">
   <query xmlns="http://jabber.org/protocol/disco#items">
      <!—some other items -->
      <item jid="proxy. myHost " name="Socks 5 Bytestreams Proxy"/>
      <!—some other items -->
   </query>
</iq>

Here you will receive various items for different items supported by server like , file transfer proxy, search service, conference service… The item we should look for is ` Socks 5 Bytestreams Proxy `.

  • Request for more information on proxy

Sent:

<iq id="x1ixz-19" to="proxy. myHost " type="get">
   <query xmlns="http://jabber.org/protocol/bytestreams"/>
</iq>

Received:

<iq type="result" id="x1ixz-19" from="proxy. myHost "  to="user1@ myHost /Smack">
   <query xmlns="http://jabber.org/protocol/bytestreams">
      <streamhost jid="proxy. myHost " host=" myHost " port="7777"/>
   </query>
</iq>

Here the host in the <streamhost> is the key for the file transfer. You have to make sure that this host is accessible from your android phone. It should not be like localhost, 127.0.0.1 or any company’s internal configured server which is not accessible outside of the company. It must be a publicly accessible ip address or host.

To configure proper proxy add/change these 3 properties in Openfire:

  1. xmpp.proxy.enabled                – true
  2. xmpp.proxy.port                        – 7777
  3. xmpp.proxy.externalip            – [publicly accessible host or ip]

The code for file transfer:

FileTransferManager manager = new FileTransferManager(connection);
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("usre2@myHost/Smack");
File file = new File(filenameWithPath);
try {
   transfer.sendFile(file, "test_file");
} catch (XMPPException e) {
   e.printStackTrace();
}
while(!transfer.isDone()) {
   if(transfer.getStatus().equals(Status.error)) {
      System.out.println("ERROR!!! " + transfer.getError());
   } else if (transfer.getStatus().equals(Status.cancelled)
                    || transfer.getStatus().equals(Status.refused)) {
      System.out.println("Cancelled!!! " + transfer.getError());
   }
   try {
      Thread.sleep(1000L);
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
}
if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error)
 || transfer.getStatus().equals(Status.cancelled)){
   System.out.println("refused cancelled error " + transfer.getError());
} else {
   System.out.println("Success");
}

And the code for file receive:

FileTransferManager manager = new FileTransferManager(connection);
manager.addFileTransferListener(new FileTransferListener() {
   public void fileTransferRequest(final FileTransferRequest request) {
      new Thread(){
         @Override
         public void run() {
            IncomingFileTransfer transfer = request.accept();
            File mf = Environment.getExternalStorageDirectory();
            File file = new File(mf.getAbsoluteFile()+"/DCIM/Camera/" + transfer.getFileName());
            try{
                transfer.recieveFile(file);
                while(!transfer.isDone()) {
                   try{
                      Thread.sleep(1000L);
                   }catch (Exception e) {
                      Log.e("", e.getMessage());
                   }
                   if(transfer.getStatus().equals(Status.error)) {
                      Log.e("ERROR!!! ", transfer.getError() + "");
                   }
                   if(transfer.getException() != null) {
                      transfer.getException().printStackTrace();
                   }
                }
             }catch (Exception e) {
                Log.e("", e.getMessage());
            }
         };
       }.start();
    }
 });

Also configure ProviderManager to properly decode/parse bytestreams and other required xmls:

ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());

The asmack library I used was asmack-jse-buddycloud.jar.

Let me know your feedbacks and if you have configured all things well and still face the issue the please drop a comment on this post; I will try my best to help you.  :)

About these ads

About harryjoy
A passionate self-taught software developer. Currently working as Software Engineer in an IT company located in INDIA.

77 Responses to File transfer in android with asmack and Openfire

  1. ewix says:

    Thank you for this article. I’ve been trying to implement file transer unsuccesfully. Unfortunately, your suggestions still did not solve my problem, which despite all the efforts is always the same. “Service-unavailable” when sending files and no errors, but not transfer (progress on the other side doesn’t increase). I’m testing on android and spark as other client, on an external openfire server (accessible without problems). I’m really not getting where the problem lies. If you have anymore suggestions…please, they are more then welcomed!

    • harryjoy says:

      Hi Ewix,

      As far as I know (503) service unavailable means the server you are using does not support the implementation of the feature you are trying to use. Check and verify that your smack and server are using same version of specification for file transfer. It can be possible that your server supports file transfer but specification it uses is different or of different version than you have in smack.

      • ewix says:

        actually the problem was a different one: I was not getting the resource name of the sender correctly (the /Spark 2.6.3 for instance): once I corrected that the file got sent without any problems from android to Spark. Not I still have the issue of receiving files: the listener fires, the path on the sdcard is correct but I always only get a 0byte file

        • ewix says:

          I gotta correct that…now I’m able to receive files as well! Thank you for your posting, it was really really useful

          • harryjoy says:

            Hi,
            Good to know that my post helped you and you got it working. Keep visiting for more cool and helpful posts.

            Thanks and Regards.

            • Viraj says:

              I have tried the same but not able to transfer file. Login and messaging works fine though.
              Every time I am sending file at other side (spark). File progress is 0 and stopped in some seconds.
              And android side it is just negotiating stream progress : 0.0

              Here is my sending file code

              ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
              ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
              ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
              ProviderManager.getInstance().addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
              					
              ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
              if (sdm == null)
                  sdm = new ServiceDiscoveryManager(connection);
              			
              sdm.addFeature("http://jabber.org/protocol/disco#info");
              sdm.addFeature("http://jabber.org/protocol/disco#item");
              sdm.addFeature("jabber:iq:privacy");
              					
              FileTransferManager manager = new FileTransferManager(connection);
              FileTransferNegotiator.setServiceEnabled(connection, true);
              OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(user2destination);	//Watch Out!!..
              File extStore = Environment.getExternalStorageDirectory();
              			
              File file = new File(extStore.getAbsolutePath()+"/finalscope.txt");
              				
              long length = file.length();
              try {
                 transfer.sendFile(file, "test_file");
              } catch (XMPPException e) {
                 e.printStackTrace();
              }
              while(!transfer.isDone()) {
                 if(transfer.getStatus().equals(Status.error)) {
                    System.out.println("ERROR!!! " + transfer.getError());
                 } else if (transfer.getStatus().equals(Status.cancelled)
                                  || transfer.getStatus().equals(Status.refused)) {
                   System.out.println("Cancelled!!! " + transfer.getError());
                 }
              try {
                    Thread.sleep(1000L);
              			      
                    Log.i("transfer file", "sending file status :- " + transfer.getStatus() + " "
                              + "progress:-" + transfer.getProgress());
              					      
              } catch (InterruptedException e) {
                    e.printStackTrace();
              }
              }
              if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error)
              		 || transfer.getStatus().equals(Status.cancelled)){
                 System.out.println("refused cancelled error " + transfer.getError());
              } else {
                 System.out.println("Success");
              }
              
          • Hello Ewix, even i am also not able to transfer the file. can u please tell me what are correct version of jar file which we need to use for the both server and android

            • harryjoy says:

              Hi Sravani,

              First of all Ewix will not get notified this way unless and until if visits this site very often, as this is not his site. (This is second time I’m writing this, may be ewix is getting more famous than in me in my site and I should invite him as an admin to the site :P )

              And second, as answer to your question, I have used asmack-jse-buddycloud.jar and latest open fire server.

              Thanks & Regards.

  2. Gaurav Arora says:

    Ewix before this thing I have a problem in adding the friends to my chat list, Can you plzzzzz help me in the same. Here is my problem posted on the stack overflow. No body is replying me and I have to work on the same yr. Please help me.

    http://stackoverflow.com/questions/12812855/android-add-friend-using-smack

    Thanks

    • harryjoy says:

      Hi Gaurav,

      First of all Ewix will not get notified this way unless and until if visits this site very often, as this is not his site.

      Second thing about your problem of adding friends, it seems like you have not changed the Subscription mode in roster. Change it to manual and you will get the notification. To change the subscription mode do as follows:

      roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
      

      And then you will receive Presence packets for add requests which will have type equal to Subscribe. To listen to this presence you can either add packet listener to connection with packet type filter for Presence class or you can add roster listener and listen this in its presenceChanged method.

  3. Gaurav Arora says:

    Hello harry joy,
    Actually I tried what u said and deleted my code :( Can you please help me by taking the code example for how can I send one notification that so and so friend wants to add you or have added. Please reply me bro. I am in big problem and wants to solve it fast.
    Thanks very much for the reply bro

    • harryjoy says:

      Hi Gaurav,

      Here are some code highlights to help you better:

      1. Set subscription mode for roster request to manual after you successfully get logged in

      //---- after successful login
      roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
      

      2. Now to add a roster you have to send a Presence packet with type equal to Subscribe. For this you can use Roster class’ createEntry method.

      roster.createEntry(userId, "userAlias", new String[]{"userGroup"});
      

      3. As I said in previous comment you can listen to this event by adding a packet listener to connection with PacketFilter of Presence class.

      connection.addPacketListener(new PacketListener() {
         @Override
         public void processPacket(Packet packet) {
            // here you have to check if request is for adding a buddy or just simple presence change event
            Presence pres = (Presence) pack;
            if (pres.getType().equals(Presence.Type.subscribe)) {
               // request handling code will go here.
               // here you have to show a notification to the user that someone is trying to add you in 
      his buddy list
               // you can get the jid of user who is trying to add you as pres.getFrom();
            }
         }
        }, new PacketTypeFilter(Presence.class));
      

      This is it! :) Hope this helps you.

      • Gaurav Arora says:

        Hello,
        Now I understand what you are saying but actually when I debugged the code I saw that the debugger actually doesn’t comes in the process packet part. What’s the error can you please tell me? :(
        Here is my code

        if (!roster.contains(idExtension)) {
        try {
           roster.setSubscriptionMode(Roster.SubscriptionMode.manual);
           roster.createEntry(idExtension, nickname, null);
           /*Presence subscribe = new Presence(Presence.Type.subscribe);
           subscribe.setTo(idExtension);				
           connection.sendPacket(subscribe);	*/
           connection.addPacketListener(new PacketListener() {
           @Override
           public void processPacket(Packet arg0) {
              Presence presence = (Presence)pac;
              if(presence.getType().equals(Presence.Type.subscribe)){
                  System.out.println("Hello Worlddddddddddddddddddd");
              }
           }
        },new PacketTypeFilter(Presence.class));
        
        • harryjoy says:

          Hi Gaurav,

          Make sure you are checking it with the correct user id. It will go in this listener method for the user to whom you are sending the request, in your case ‘idExtension’ is the user who will receive the the request packet in processPacket method. It will not go inside the method at the initiator side means from which you are sending the request.

          Regards.

          • Gaurav Arora says:

            Hi bro,
            Its all rite at our end but the code is not executing at all ( the process packet one)

            Can you please help ??

            • harryjoy says:

              Hi,

              This is the small example I can come up with to make you understand what I’m saying. Run this class and you will understand what I am trying to say.

              import java.awt.EventQueue;
              import java.awt.FlowLayout;
              import java.awt.event.ActionEvent;
              import java.awt.event.ActionListener;
              
              import javax.swing.JButton;
              import javax.swing.JFrame;
              import javax.swing.JOptionPane;
              
              import org.jivesoftware.smack.ConnectionConfiguration;
              import org.jivesoftware.smack.PacketListener;
              import org.jivesoftware.smack.Roster;
              import org.jivesoftware.smack.XMPPConnection;
              import org.jivesoftware.smack.XMPPException;
              import org.jivesoftware.smack.filter.PacketTypeFilter;
              import org.jivesoftware.smack.packet.Packet;
              import org.jivesoftware.smack.packet.Presence;
              
              public class AddRoster {
              	private static final String host = "myHost"; 
              	private static final int port = 5222; 
              	private static final String user_1_id = "user1"; // request initiator user
              	private static final String user_1_pass = "password"; 
              	private static final String user_2_id = "user2"; // request receiver user
              	private static final String user_2_pass = "password"; 
              	public static void main(String[] args) {
              		EventQueue.invokeLater(new Runnable() {
              			@Override
              			public void run() {
              				JFrame frame = new JFrame("Add user");
              				frame.setLayout(new FlowLayout(FlowLayout.CENTER));
              				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              				JButton button = new JButton("Add user in my list");
              				button.addActionListener(new ActionListener() {
              					@Override
              					public void actionPerformed(ActionEvent e) {
              						ConnectionConfiguration configuration = new ConnectionConfiguration(host, port);
              						XMPPConnection connection = new XMPPConnection(configuration);
              						try {
              							connection.connect();
              							connection.login(user_1_id, user_1_pass);
              							connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.manual);
              							connection.getRoster().createEntry(user_2_id + "@" + host, "add user test", new String[]{"Default"});
              						} catch (XMPPException e1) {
              							e1.printStackTrace();
              						}
              					}
              				});
              				frame.add(button);
              				frame.setSize(200, 200);
              				frame.setVisible(true);
              
              				final JFrame frame2 = new JFrame("Listen to add user request");
              				frame2.setLayout(new FlowLayout(FlowLayout.CENTER));
              				frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              				JButton button2 = new JButton("Start listening to events");
              				button2.addActionListener(new ActionListener() {
              					@Override
              					public void actionPerformed(ActionEvent e) {
              						ConnectionConfiguration configuration = new ConnectionConfiguration(host, port);
              						XMPPConnection connection = new XMPPConnection(configuration);
              						try {
              							connection.connect();
              							connection.login(user_2_id, user_2_pass);
              							connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.manual);
              							connection.addPacketListener(new PacketListener() {
              								@Override
              								public void processPacket(Packet packet) {
              									Presence presence = (Presence) packet;
              									if (presence.getType().equals(Presence.Type.subscribe))
              										JOptionPane.showMessageDialog(frame2, "New buddy request from: " + presence.getFrom());
              								}
              							}, new PacketTypeFilter(Presence.class));
              							System.out.println("Started listening to events");
              						} catch (XMPPException e1) {
              							e1.printStackTrace();
              						}
              					}
              				});
              				frame2.add(button2);
              				frame2.setSize(200, 200);
              				frame2.setVisible(true);
              			}
              		});
              	}
              }
              

              Before running this change the private variables with appropriate values. Then when you run the class, first click on “Start listening to events” button. And when you see “Started listening to events” on console, click on “Add user in my list” button. Once it runs successfully, you can use relevant code part in your application.

              • Gaurav Arora says:

                Thanks Harry, I was able to achieve the same by some other means. Its ok now no problem.
                Harry, but now I am facing a problem when I chat with my friend, me and my friend have to be on same chatting screen then only we receive each others message. How can I send a notification to my friend if he is not on the same chat screen or he is working on any other screen??

                • harryjoy says:

                  Hi Gaurav,

                  Sorry but this is not a QA forum where I will answer all your questions or help you build your app. Please ask such questions on some QA site. Anyways as a hint what you do is run a packet listener of message class in a service in its process method check for sender and check if it is same to which you are currently chatting or not. If not then show a notification.

                  Regards,
                  Harsh raval.

  4. Gaurav Arora says:

    Harry,

    I am implementing File Transfer in my application and I am getting null pointer exception on this line:
    FileTransferManager ftm = new FileTransferManager(connection);

    now after studying the solution from the stackoverflow, now I have added one more line with it as :

    new ServiceDiscoveryManager(connection);

    FileTransferManager ftm = new FileTransferManager(connection);

    Now no force close is coming but my code is not working also.

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == LOAD_IMAGE_GALLERY && resultCode == RESULT_OK && null != data) {
    Uri selectedImage = data.getData();
    String[] filePathColumn = { MediaStore.Images.Media.DATA };

    Cursor cursor = getContentResolver().query(selectedImage,
    filePathColumn, null, null, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String picturePath = cursor.getString(columnIndex);
    cursor.close();

    System.out.println(“Path Of the Image “+picturePath);

    new ServiceDiscoveryManager(connection);

    FileTransferManager ftm = new FileTransferManager(connection);
    OutgoingFileTransfer transfer = ftm.createOutgoingFileTransfer(“abc@hostname.com/Smack”);
    File file = new File(picturePath);

    try {
    transfer.sendFile(file, “test_file”);
    Toast.makeText(getApplicationContext(), “Sending file..”, Toast.LENGTH_SHORT).show();

    } catch (XMPPException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    while(!transfer.isDone()){

    if(transfer.getStatus().equals(Status.error)){

    System.out.println(“Error!!”+transfer.getError());

    }
    else if (transfer.getStatus().equals(Status.cancelled)||transfer.getStatus().equals(Status.refused)){
    System.out.println(“Cancelled/Refused”+transfer.getError());
    }

    try {
    Thread.sleep(1000L);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    }

    }

    Please reply if you can.

    • harryjoy says:

      What do you mean by not working? Is it throwing any exception or anything else? Describe “not working” in detail.

      Regards.

      • Gaurav Arora says:

        Hi harry,
        I want to tell you the thing that when I click on the photo nothing happens ( no force close ) no error. and when I debugged the app I saw that the cursor is not even coming on the line FileTranfer ftm… and directly moves the last line i.e Toast – Sending File..

        Thanks

        Please help me

  5. juned says:

    Hi Harryjoy,

    Thanks for such nice tutorial. I am struggling with same issue of file transfer and finally i got your blog.I am going to follow your steps but at first step my question is where do i find those xml files ?

    Thanks

    • harryjoy says:

      Hi,

      Xml shown here is not a part of any file. They are xml presentation of packets transferred between client and server. If you are using asmack then enable debug option in code and you will see such xml in logs.

      Regards.

      • juned says:

        Hi Thanks for reply i got this error while running the project.

        10-31 10:40:50.528: E/AndroidRuntime(25546): FATAL EXCEPTION: main
        10-31 10:40:50.528: E/AndroidRuntime(25546): java.lang.VerifyError: org.jivesoftware.smack.sasl.SASLMechanism
        10-31 10:40:50.528: E/AndroidRuntime(25546): at java.lang.Class.getDeclaredConstructors(Native Method)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at java.lang.Class.getConstructor(Class.java:472)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:303)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at org.sipchat.sipua.ui.SettingsDialog.(SettingsDialog.java:89)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at org.sipchat.sipua.ui.XMPPClient.onCreate(XMPPClient.java:230)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.os.Handler.dispatchMessage(Handler.java:99)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.os.Looper.loop(Looper.java:123)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at android.app.ActivityThread.main(ActivityThread.java:3683)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at java.lang.reflect.Method.invokeNative(Native Method)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at java.lang.reflect.Method.invoke(Method.java:507)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
        10-31 10:40:50.528: E/AndroidRuntime(25546): at dalvik.system.NativeStart.main(Native Method)

  6. juned88 says:

    Hi Harryjoy,

    Thanks for such a nice tutoria. i am struggling with same issue of file transfer. I am going to follow this steps but my my question is where do i get those xml files?

    Thanks

  7. Gaurav Arora says:

    Hello Harry,

    Please help me in this matter bro. Here is great problem for me.

    stackoverflow link : http://stackoverflow.com/questions/13302178/xmpp-with-smack-adding-friend

    Please help and I know you can help me.

    Thanks

  8. Gaurav Arora says:

    Hello harry,

    File transfer using XMPP methods/libraries is not at all reliable and takes much time.

    Please have a look on my scenario, if you can please help me

    http://stackoverflow.com/questions/14601198/sending-pictures-like-whats-app

    I shall be very thankful to you

    Thanks

  9. Vinod says:

    Harry,

    First of a good tutorial , i have not started implementing this yet but i have few questions which caught while i was looking through your code.

    1. As in basic normal file transfer in android apps, from app to server we need to compress the image a lot so that they don’t crash the app while transfer. Like new android mobiles take images which are at a size of more than 1mb or 2mb , if we transfer these files the app cant take the load and crashes out so we need to compress them a lot. My question is in the chat app do we need to compress the image in similar way before transferring or is it taken care by Openfire or XXMP?

    2. Can we use the same code for video upload ?

    3. Video sizes will be huge as i have seen in normal app we are able to upload videos below size of 1mb , video above 1mb crashes out.

    a. Can you tell me is it possible to upload above 1mb too here in chat app? .
    b. If yes is it that we need to compress the video and upload or not ?
    c. If video need to be compressed can you please help me on this how can this be done on android , if you have a sample or tutorial it would be great help for one of my other android apps too.

    Waiting to know more on these from you, please do reply.

    Thanks

    • harryjoy says:

      Hi Vinod,

      Answers are as follows:

      1) no you have to do it, openfire will not handle it..
      2) yes
      3) I’m not sure about how to compress the video, but you can find it online give a try.

      Thanks,

      • Vinod says:

        Harry,

        Good the hear from you, thanks for your answers.

        Ok that means i need to do the byte compression at android app end and then send it across.

        I have tried searching around for compressing the video on android but couldn’t find anything useful still.

        One more question i got is that we cant test file transfer on emulator ? As i read through your post i got such an understanding , let me know am i right ?

        My chat app has MUC and File Transfer, if i use “asmack-jse-buddycloud.jar.” my MUC doens’t work because of some code issue and if i used the jar in which MUC works in that case file transfer throws null pointer error in the code for which we receive the file transferred. To fix this i followed this post and i got issue fixed with my old jar file

        http://community.igniterealtime.org/thread/41391.

        Just for anyone comes across this issue.

        • harryjoy says:

          Vinod,

          Yes you can test it on emulator. About using jar, in this post I have just shown way to do file transfer but yes one needs to configure other IQProvider and Extensions to work with other functionality of chat smoothly.

          Thanks.

  10. Bala says:

    Harry,

    Tried out the above code but still i am getting a error 404. remote-sever-not-found

    Thanks

    • harryjoy says:

      Hi Bala,

      It seems like your mobile network is not able to connect to file transfer host. Did you properly checked the host in file transfer? It should not be a host or ip that is not pingable from the mobile.

      Thanks and regards.

  11. Vinod says:

    Harry,

    I have a dedicated server on which openfire is installed and i am building an app. I am trying file transfer over it now.

    I have followed you blog and according to that i am able to connect from one user to other while transferring file but i am getting this following error.

    05-14 00:27:29.982: I/System.out(318): File Name Received/mnt/sdcard/DCIM/Camera/test.jpg
    05-14 00:27:29.982: E/(318): Could not create file to write too

    The file path building the file is as used as below

    File mf = Environment.getExternalStorageDirectory();File file = new File(mf.getAbsoluteFile()+”/DCIM/Camera/” + transfer.getFileName());

    I am testing file transfer from phone to emulator i.e from phone i choose photo and transfer to emulator.

    Can you tell me y i am not able to create a file to write too is it the file path issue or is it that i can create a file on emulator ?

    Thanks

    • harryjoy says:

      Hi Vinod,

      It seems like you have not given permission to write on external card. If not given then write following line in manifest:

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      

      For more and better help, please provide full stack trace of the exception.

      Thanks.

      • Vinod says:

        Harry

        I have already added these in my manifest

        Here the file it getting written to emulator storage not to the phone storage. Is this an issue ?

        Thanks

        • harryjoy says:

          Hi Vinod,

          Provide stack trace of the exception. When you get this exception, use “e.printStackTrace()” to print it’s stack trace. (Assuming e is the reference to the exception being caught.)

          Thanks.

    • Plinio says:

      Hi Harry,

      Hen creating the AVD, ensure that you are setting a size to it – it is not done by default. Without that, no sdcard is created and you can not write to sdcard at all.

      BR,

  12. Vinod says:

    Harry,

    i have created a stack overflow message for this issue added few logs too can you please check and help me out of this,

    http://stackoverflow.com/questions/16547484/xmpp-asmack-filetransfer-giving-error-when-the-file-is-received

    Thanks

    • Vinod says:

      Harry,

      I was out of station so was not able to reply on this chain. I was able to sort out the issue, it was basically the file path, i was fetching image and compressing it while compressing the file path was changed as a temporary file on sdcard. This file path had to be same on the receiving user side too (this one i had a different one so it was not downloading the image).

      Ones i gave the same file path on receiver side it started transferring the image properly.

      I have one question, the to username in file transfer needs to be with “/Smack” resource. Now my app is being built on iphone too so i need to get the resource of the user how do i do this ? How can i get the resource of the receiving side user ?

      Thanks

      • harryjoy says:

        Hi Vinod,

        You can use getRequestor method of FileTransferRequest when you receive the file.

        public String getRequestor()

        This will return you the JID of the user who wants to transfer the file. This will be the user’s id with resource so you can have complete JID with resource that you can process. Or else to extract only resource from this JID, you can use StringUtils class’ parseResource(String XMPPAddress) method to get resource name out of it.

        And if you are talking about setting resource of logged in user then you can use login method of XMPPConnection class which takes 3 argument where 3rd argument is the resource name to be used for user.

        Regards.

  13. azep291 says:

    I just want to share. If you have problems both transfering or receiving file, maybe it caused by the RESOURCE of your friend is. For example, the code :

    OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(“user2@myHost/Smack”);

    “Smack” is your friend resource. So you have to change it with Fully JID, for example : user2@myHost/Spark 2.6.3

    Hopefully may solve your problems.

    • harryjoy says:

      Hi azep291,

      Yes this definitely helps. The resource should also match while transferring file. Thanks for sharing. :)

      Regards.

      • suprayoghie says:

        The resource also helps me too. But I have problem in getting Roster/friend Resource. When roster/friend connected by using Spark, full JID will be “friend@host/Spark 2.63″ for example.

        Maybe you have any solution in getting roster/fried resource.
        Thank you :)

        • harryjoy says:

          Hi,

          You can use StringUtils class from Smack jar. It has a method called parseResource(String XMPPAddress) which returns resource name from JID.

          Thanks.

  14. Nitish Singla says:

    Hello harryjoy,
    i am follow your Link for File transfer with asmack and openfire,But getting problem:-
    Empty file is received on other device while transferring file one device to another,its show the 0KB size.i mean when i opened it,its shows blank screen.i do not know what’s the problem behind it,,Plzz help me…

    My code and Log files are Present on this link:
    http://stackoverflow.com/questions/17608424/file-transfer-show-file-size-0kb-while-transfering-file-using-smack-in-android

  15. jithu says:

    am able to recevie the file,but while am sending the file ,it gives a 503 error service not aviloable,plz check this stackoverflow question which i posted,plz give me a solution. http://stackoverflow.com/questions/17921288/xmpp-filetransnfer-in-android-giving-503-service-unavailable-error

  16. Muhammad ShahNawaz says:

    Hey Dear Brother I am working with asmack but it is giving me a strange exception while sending a file. It works fine for the message sending but not allowing the file sending. Follwing is the code that I am trying.I am picking a file from sdCard. It is fine I have checked the file it exists and gives right path. Under the code I have also added the Log messages.

    if (resultCode == RESULT_OK)
    {
    Uri uri = data.getData();
    Log.d(“URI”, uri.toString());

    File nfile=new File(Environment.getExternalStorageDirectory().toString()+”/”+uri.toString());
    Log.v(“”, nfile.getAbsolutePath());
    // Create the outgoing file transfer
    FileTransferManager ftm = new FileTransferManager(
    connection);
    OutgoingFileTransfer transfer = ftm.createOutgoingFileTransfer(recipient.getText().toString());
    try {
    transfer.sendFile(nfile, “Hello Jigar”);

    } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    catch (XMPPException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    08-13 14:01:42.260: D/URI(15466): file:///mnt/sdcard/c.v.pdf
    08-13 14:01:42.260: V/(15466): /mnt/sdcard/file:/mnt/sdcard/c.v.pdf
    08-13 14:01:42.310: W/System.err(15466): java.lang.IllegalArgumentException: Could not read file
    08-13 14:01:42.310: W/System.err(15466): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.sendFile(OutgoingFileTransfer.java:206)
    08-13 14:01:42.310: W/System.err(15466): at com.swenggco.androidxmpp.ChatClient.onActivityResult(ChatClient.java:214)
    08-13 14:01:42.320: W/System.err(15466): at android.app.Activity.dispatchActivityResult(Activity.java:4740)
    08-13 14:01:42.320: W/System.err(15466): at android.app.ActivityThread.deliverResults(ActivityThread.java:3383)
    08-13 14:01:42.320: W/System.err(15466): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3437)
    08-13 14:01:42.320: W/System.err(15466): at android.app.ActivityThread.access$1100(ActivityThread.java:139)
    08-13 14:01:42.320: W/System.err(15466): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1291)
    08-13 14:01:42.320: W/System.err(15466): at android.os.Handler.dispatchMessage(Handler.java:99)
    08-13 14:01:42.320: W/System.err(15466): at android.os.Looper.loop(Looper.java:154)
    08-13 14:01:42.330: W/System.err(15466): at android.app.ActivityThread.main(ActivityThread.java:4945)
    08-13 14:01:42.330: W/System.err(15466): at java.lang.reflect.Method.invokeNative(Native Method)
    08-13 14:01:42.330: W/System.err(15466): at java.lang.reflect.Method.invoke(Method.java:511)
    08-13 14:01:42.330: W/System.err(15466): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    08-13 14:01:42.330: W/System.err(15466): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    08-13 14:01:42.330: W/System.err(15466): at dalvik.system.NativeStart.main(Native Method)

    Please Help me I will be very thankfull to you.

    • harryjoy says:

      Hi Muhammad,

      It seems like your app is not able to find the file specified. Since you are reading form sd card, have your provided permission to read from sd card? If not then read this: http://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE it will help you to do it.

      Thanks & Regards.

      • Muhammad ShahNawaz says:

        Thanks for the response. Yes I have provided the permisions

        .
        Now I have changed the code a bit and now It always says request confused to accept file.
        I am currently using these parametters to make connection.

        ConnectionConfiguration connectionConfig = new ConnectionConfiguration(
        “talk4.l.google.com”, Integer.parseInt(“5222″), “gmail.com”);

        please help. Is it due to the service? Means is googletalk not allowing it or some thing else? Plus can we chat right now I can email you my code if you can help it will be really nice. Also, at which service I should test this if not google talk?

        Waiting for your kind response.

  17. krishna says:

    I have tried your code. I m getting error while sending a file. I am getting null error. i.e. refused cancelled error null

    • harryjoy says:

      Hi krishna

      It seems like you have NPE in there. Check your variables debug mode to see which required thing is null. once you get cause of npe, resolve it and try see again to see if it works for you.

      Thanks.

      • krishna says:

        Actually i have debugged the code. XMPPException generates in the line treansfer.sendFile().
        I think the problem is of service unavailable 503

  18. krishna says:

    The problem occuring is of version I think so. My openfire server version is 3.7.1 and smack version is 3.1.0. So can I know what can I do further to run my code properly to transfer the code

  19. Gaurav Arora says:

    Hi Harry,

    I have used your above described methods for file transfer and receiving with my chat application. But I am getting this very response during file transfer :

    10-21 12:31:41.161: I/transfere file(6112): Error is: nullTarget returned an error: feature-not-implemented(501)

    Please let me know what is the problem with my application.

    Thanks

    • harryjoy says:

      Hi Gaurav,

      It seems like your server doesn’t have the feature for file transfer or it is disabled. Please check for the same and then try again by either installing the missing feature or enabling it.

      Regards.

      • Gaurav Arora says:

        Hi Harry,

        I have double checked in Openfire Server Portal – File Transfer Settings. It is enabled well and a port number is also written.

        Now please let me know the possible problem/cause for my problem?

        • harryjoy says:

          Can you confirm this by doing file transfer from desktop client and from desktop client to android and reverse?

          Regards.

          • Gaurav Arora says:

            Hi Harry, It is not working on either side. On sender’s side error 501 is coming and on receiver side following errors/warnings are coming.

            10-25 12:23:07.929: I/Recieve File(6920): new file transfere request new file transfer request new file transfer request
            10-25 12:23:07.929: I/file request(6920): from: ramu@ec202.abcd.com/Smack
            10-25 12:23:07.929: I/Recieve File alert dialog(6920): accepted
            10-25 12:23:07.929: W/System.err(6920): Could not create file to write too:
            10-25 12:23:07.929: W/System.err(6920): — caused by: java.io.IOException: Permission denied
            10-25 12:23:07.929: W/System.err(6920): at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.recieveFile(IncomingFileTransfer.java:109)
            10-25 12:23:07.929: W/System.err(6920): at com.abc.CCM.BootReceiver.UpdaterService$7$1.fileTransferRequest(UpdaterService.java:709)

          • Gaurav Arora says:

            Sometimes this exception also comes at the receiver’s end (Connection Refused). I am stuck in this File Transfer Scenario. Please help me.

            10-25 12:45:38.173: D/SMACK(593): 12:45:38 PM RCV (1121099488):
            10-25 12:45:38.188: W/System.err(593): java.net.ConnectException: failed to connect to /127.0.0.1 (port 7777): connect failed: ECONNREFUSED (Connection refused)
            10-25 12:45:38.188: W/System.err(593): at libcore.io.IoBridge.connect(IoBridge.java:114)
            10-25 12:45:38.193: W/System.err(593): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
            10-25 12:45:38.193: W/System.err(593): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
            10-25 12:45:38.198: W/System.err(593): at java.net.Socket.startupSocket(Socket.java:566)
            10-25 12:45:38.198: W/System.err(593): at java.net.Socket.tryAllAddresses(Socket.java:127)
            10-25 12:45:38.198: W/System.err(593): at java.net.Socket.(Socket.java:177)
            10-25 12:45:38.203: W/System.err(593): at java.net.Socket.(Socket.java:149)
            10-25 12:45:38.203: W/System.err(593): at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.selectHost(Socks5TransferNegotiator.java:196)
            10-25 12:45:38.208: W/System.err(593): at org.jivesoftware.smackx.filetransfer.Socks5TransferNegotiator.negotiateIncomingStream(Socks5TransferNegotiator.java:114)
            10-25 12:45:38.208: W/System.err(593): at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator$NegotiatorService.call(FaultTolerantNegotiator.java:181)
            10-25 12:45:38.208: W/System.err(593): at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator$NegotiatorService.call(FaultTolerantNegotiator.java:166)
            10-25 12:45:38.208: W/System.err(593): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            10-25 12:45:38.208: W/System.err(593): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            10-25 12:45:38.208: W/System.err(593): at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
            10-25 12:45:38.208: W/System.err(593): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            10-25 12:45:38.213: W/System.err(593): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            10-25 12:45:38.213: W/System.err(593): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            10-25 12:45:38.213: W/System.err(593): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            10-25 12:45:38.213: W/System.err(593): at java.lang.Thread.run(Thread.java:856)
            10-25 12:45:38.213: W/System.err(593): Caused by: libcore.io.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
            10-25 12:45:38.213: W/System.err(593): at libcore.io.Posix.connect(Native Method)
            10-25 12:45:38.213: W/System.err(593): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
            10-25 12:45:38.218: W/System.err(593): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
            10-25 12:45:38.218: W/System.err(593): at libcore.io.IoBridge.connect(IoBridge.java:112)
            10-25 12:45:38.218: W/System.err(593): … 18 more

  20. Ashwini Saraf says:

    hey plz send me the code of multi chat user.how to create it?

  21. vahid says:

    Hi, I’m trying to setup a basic test sample of file transfer useing SIP XEP-0096 XMPP extension.

    for may test case I run openfire on CentOS6.4-64Bit Virtual Box. iptables is off.

    Storage solution is based on DB (mysql).

    It seems that receiver doesn’t negotiates well with the sender, Could you please have a look at logcats and my sample code(Attached)?

    Sender LogCat Main Part:

    Start Sending . . .

    avatar1.pnghttp://jabber.org/protocol/bytestreamshttp://jabber.org/protocol/ibb

    Sender gets No submit from receiver, it seems receiver gets request but Listener is not invoked!

    LogCat of receiver is:

    avatar1.pnghttp://jabber.org/protocol/bytestreamshttp://jabber.org/protocol/ibb

    That’s it, Nothing more!!!

    I’m working on a customized version of Xabber Client (https://github.com/redsolution/xabber-android/).

    Thanks a lot

  22. vahid says:

    unfortunately I was unable to add my code, so, please refer to link bellow for full ticket discussion:

    http://community.igniterealtime.org/message/236740

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 53 other followers

%d bloggers like this: