File transfer in android with asmack and Openfire
August 18, 2012 51 Comments
I have seen many peoples struggling from file transfer in asmack – Android 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:
- xmpp.proxy.enabled – true
- xmpp.proxy.port – 7777
- 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. :)
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!
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.
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
I gotta correct that…now I’m able to receive files as well! Thank you for your posting, it was really really useful
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.
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");
}
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
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:
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.
Hello harry joy,
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.
Actually I tried what u said and deleted my code
Thanks very much for the reply bro
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
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.
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));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.
Hi bro,
Its all rite at our end but the code is not executing at all ( the process packet one)
Can you please help ??
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.
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??
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.
Ok Thanks bro for helping me.
Actually now I am stuck in a very severe situation but i am sure you would surely know the solution to handle the same. Please have a look bro on this. http://stackoverflow.com/questions/12948442/xmpp-presence-subscription
If you can help me I would be very thankful to you man
Thanks in advance
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.
What do you mean by not working? Is it throwing any exception or anything else? Describe “not working” in detail.
Regards.
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
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
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.
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)
i am using smack api, should i use i asmack?? if yes then please provice me relevant link. i want to get it working any how
Thanks
It depends on platform you are developing the application for. If you are developing android application then use asmack else for developing desktop and web app use smack. Regarding links for the jar, you can easily search this jar files on internet. Just Google it.
Best Regards.
Hi Harryjoy,
I tried to do file transfer but still i am getting a error. My application is crashes on this line
FileTransferManager manager = new FileTransferManager(connection);
And yeah now i am using asmack-jse-buddycloud-2010.12.11.jar. Messages are fine but application crashes on above line, here is my code
http://pastie.org/5364412
I am using this sampe chat tutorial
http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/
Please help me on this and if i am on wrong direction.
Thanks & Regards
Hi Harryjoy,
I tried to do file transfer but still i am getting a error. My application is crashes on this line
FileTransferManager manager = new FileTransferManager(connection);
And yeah now i am using asmack-jse-buddycloud-2010.12.11.jar. Messages are fine but application crashes on above line, here is my code
http://pastie.org/5364412
I am using this sampe chat tutorial
http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/
Please help me on this and if i am on wrong direction.
Thanks & Regards
Hi juned,
Which error do you get when application crashes?
Thanks for response,
Now my application is not crashing but yet file is not being recieved. here is my code please check this http://paste.ubuntu.com/1562112/
You are using localhost.localdomain as host, which is not correct as I have mentioned in my post. Android does not identift localhost as a valid transfer host. Read my post once again and also check by using 2 desktop client, does file transfer works properly in desktop version? Also verify that your server supports file transfer.
Actually i am testing locally and initial chating is work fine, but i am not sure about server, i am using openfire server by the way. i guess its supports file transfer.
Thanks
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
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
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
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
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,
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.
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.
Harry,
Tried out the above code but still i am getting a error 404. remote-sever-not-found
Thanks
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.
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
Hi Vinod,
It seems like you have not given permission to write on external card. If not given then write following line in manifest:
For more and better help, please provide full stack trace of the exception.
Thanks.
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
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.
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
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
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.
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.
Hi azep291,
Yes this definitely helps. The resource should also match while transferring file. Thanks for sharing.
Regards.
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
Hi,
You can use StringUtils class from Smack jar. It has a method called parseResource(String XMPPAddress) which returns resource name from JID.
Thanks.