Tuesday, April 1, 2014

Creating Android XMPP Client using locally installed XMPP Server

I wanted to develop an XMPP client as a part of some Android app which needs messaging capability, various XMPP servers are available for free download. I chose Ejabberd 2.1.11 because it has a windows version. I installed it, created a server named 'xmpp-server' and 'admin' user. We can start the server by double clicking the start-ejabberd icon created on desktop. It pops up a web page with a link for admin interface where we can manage the server and do stuff like creating more users etc.

I found this link very useful to develop the android app and it also provides the source code for an app named XMPPClient. I downloaded it and tried to run it. It was developed in IntelliJ, I just imported it in Eclipse and made changes where needed. I USB connected my Samsung Galaxy 3 and ran the app from eclipse directly into my mobile. 

The XMPPClient app worked perfectly, I was able to log-in (with gmail credentials) using the details provided in the screen shots in that link. I was able to send and receive messages to another google account by providing another gmail address. But my goal was to use my own XMPP server instead of gmail server. So while creating ConnectionConfiguration, I used my IP address for HOST, the port will remain same as 5222 and the service has to be modified to the XMPP server instance I created while installation (xmpp-server in my case).

ConnectionConfiguration conConfig = new ConnectionConfiguration(host, Integer.parseInt(port), service);

Both of my android device & laptop where XMPP server is running are connected to my WIFI network, so I used my LOCAL WiFi IP address of my laptop as host (make sure the XMPP server is up and running). The XMPPClient app in the above link aims to connect to gmail server so it uses smack.jar, whereas in our case we are trying to connect to an XMPP server from Android, so we have to use ASmack jar instead of Smack jar which can be downloaded here. Make sure you add the ASmack jar in lib folder of the app, add it to build path and remove smack jar.

In case if you want to use your external IP address which we can find by simply searching for IP address in google, we will have to make sure that we forward all XMPP requests received by our router to the computer where XMPP server is installed. We can achieve this with simple configurations on the router. Firstly make sure that your computer receives a static IP address (not dynamic) assigned by the router internally. We can do that by visiting the LAN setup on your router configuration link, there simply specify a allowed unused local IP address and hook it with your mac address. It should look something like the following image.


Secondly ask the router to forward the XMPP requests to your static IP (your computer) address when ever it receives a request on its 5222 port, which you can do by visiting virtual servers configurations in the Firewall settings of your router, which should look like the image below.


The updated app worked perfectly well for me. I was able to connect to my XMPP server and successfully logged in as admin & as other users too. I was able to send/ receive messages to another XMPP client. We can create more users using the XMPP admin interface, login to the server by installing app in other android devices to test it. Or we may use any XMPP client like pidgin (available for windows here), login as some user and send messages to the admin. You will be able to send & receive messages using the XMPPClient android app to Pidgin. I tested the app installing on two different android devices, was able to login as different users and was able to send/ receive messages between the two devices. Make sure the computer where XMPP server is running and the android devices are all using the same Wi-Fi network if you are working with Local IP address else if working with external IP address you may be on any network. Also make sure the recipient id should be mentioned as userID@XMPPServerInstanceName, in my case it would be hari@xmpp-server.

If you did everything correctly and still not able to connect to locally installed XMPP server using local/ external IP, you should probably check your Firewall settings which should be enabled to receive requests. On Windows make sure you turn on Network Discovery, try to troubleshoot Incoming Connections (image below) and allow to receive requests on erl.


I made lot of changes to the app and published it on the Google Play. I plan to make even more changes to it in near future. You may install it for free on any android device at this link.

The complete source code for the app (Eclipse project) is available on GitHub at this link. Feel free to download. Contributions are welcomed.

If you find any of this useful, feel free to share the blog post on twitter, G+ etc and rate the android app :)

29 comments:

  1. Hi,
    Can you share the tutorial how to build your application from scratch?

    ReplyDelete
  2. @superstar:
    Did you notice the GitHub link at the bottom. You can download complete source code for this Eclipse Android project named XMPPClient. You can directly import it into your Eclipse if you have the Android development environment (Eclipse, ADT plugin, SDKs) ready. I even provided the link to download the XMPP server I used. Try to run the XMPPXlient app in your android device/ Emulator using Eclipse. Install and start your XMPP server, then you should be able to connect from the app. Take a look at the source code and if you didn't understand something, feel free to ask here.

    ReplyDelete
  3. Replies
    1. hey if u have any demo please send me mayanklangalia@gmail.com

      Delete
  4. @tafadzwa mqetu:
    No probs buddy. What kind of app are you working on?

    ReplyDelete
  5. Hi!
    Thank you!
    I have a question. I would like to connect to a server with an external ip address. what changes should I do?

    ReplyDelete
  6. Hello Fuentes:
    You are welcome :)
    I updated the blog post and explained about how to use external IP. Take a look at it.
    You may take a look at the source code as well at GitHub also try and check out the app "XMPP Client" on Google Play.
    May I know what kind of app are you working on??

    ReplyDelete
  7. well appreciated your help with this chat app but so many apis are lost from your app
    from last 3 days i just downloaded so many smack library for this app even though have to suppress Asynctask <>
    can u tell me how to resolve AsyncTask problem in this app?????
    r this application is for cupcake version of android ?

    ReplyDelete
  8. Hello Shivani: The current latest commit on Github is version 3 of my app (XMPP Client) which needs minimum API level 7 (Android 2.1) as it uses ActionBar. It's doesn't support Cupcake (Android 1.5 & API level 3). I'm pretty sure that version 2 of my app supports Android 1.5 which you can download from a previous commit (link below), that old version of app did crash at few places where are fixed in version 3 & 4 but the code still works. You don't need to download any additional asmack jar, the app has it in lib folder, make sure you add it to build path. Try to run version 2, if you encounter the same issue again, paste the exception in detail, I'll take a look at it.

    Github link to version 2: https://github.com/gudigundla/AndroidXMPPClient/tree/73a24657d62d5473339a63115886127fe019003e

    ReplyDelete
  9. hey wana ask 1 more query is ejabber server is only solution of this chat app if i wana run it with tomcat apache may i or not ?
    as i downloaded ejabber for windows 8 it gives error when i start it some kill process node error is provided by ejabber server
    and worst part no valid solution in google?

    ReplyDelete
  10. Shivani:

    Ejabberd & Tomcat are completely two different kinds of servers. Ejabberd (xmpp server) is a messaging server where as Tomcat is a servlet container. I guess you meant JMS by Tomcat but JMS and XMPP servers are two different things (link below). You can use any xmpp server to replace ejabberd here. I preferred it because it had a windows version. here's the list of xmpp servers you may choose from http://xmpp.org/xmpp-software/servers/

    Ejabberd 2.1.11 worked fine for me on windows 7 & 8 - http://www.process-one.net/en/ejabberd/archive/

    JMS vs XMPP: http://stackoverflow.com/questions/4895259/what-is-the-difference-between-jms-and-xmpp

    ReplyDelete
  11. Sorry, Your blog has almost no information how to setup the application environment specially the V7 support. The Actionbar is not a recommended activity.
    In my case the aapt.exe keep crashing.. Although I have opened the project and compiled v7 support and then used as a library in the provided github code
    I dont understand how others compiled it or they are just too happy to use the apk only.

    ReplyDelete
  12. Use this commit on github https://github.com/gudigundla/AndroidXMPPClient/tree/73a24657d62d5473339a63115886127fe019003e
    You wont need Actionbar. This is the version of code I used when I wrote the post initially. It doesn't handle few crashes but perfectly serves the purpose.

    ReplyDelete
  13. hey hari..
    nice example,
    i get some error, when i import the full project. i got error in all file
    android.support.v7.app.actionbar
    android.support.v7.app.actionbaractivity

    is not getting recognized

    alos in file xmppvalidusertask.java

    SmackAndroid.init(client); init is not valid , it says to change to wait

    also R variable not getting recognized,

    can u help me whats wrong in this

    ReplyDelete
  14. Hi, I am having the same issues as spider. Can someone help us out ??

    R is not recognized ...

    ReplyDelete
  15. Hey buddy,
    i am working on File Transfer and i want to try between two android clients.
    FileTransferManager manager = new FileTransferManager(connection);
    OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer("usre2@myHost/Smack");

    How to get resource id(Smack in ) of the user along with jabber id (usre2@myHost/).i am using openfire and asmack lib for android.

    ReplyDelete
  16. [SettingsDialog] Connected to 192.168.168.62
    [SettingsDialog] Service Name shiva
    Could not find class 'java.beans.PropertyDescriptor', referenced from method org.jivesoftware.smack.util.PacketParserUtils.parseWithIntrospection
    VFY: unable to resolve new-instance 48 (Ljava/beans/PropertyDescriptor;) in Lorg/jivesoftware/smack/util/PacketParserUtils;
    VFY: replacing opcode 0x22 at 0x0016
    DexOpt: unable to opt direct call 0x001d at 0x18 in Lorg/jivesoftware/smack/util/PacketParserUtils;.parseWithIntrospection
    stream:error (host-unknown)
    at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:260)
    at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:43)
    at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)
    [SettingsDialog] Failed to log in as naveen
    No response from the server.:

    ReplyDelete
  17. Good one buddy thanks..!! :) do you know how to achieve Push Notification from server to app (like new updates notification to all client app or some alert ) any idea to achieve this..?

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. Hi dude.. i am doing a XMPP chat application in Android but i am facing some problem. I connected to it by the following snippet :

    ConnectionConfiguration connConfig = new ConnectionConfiguration("113.19.87.196", 5222, "biprosprod");
    XMPPConnection connection = new XMPPConnection(connConfig);
    connection.connect();

    It gives following exception :
    "XMPPError connecting to 113.19.87.196:5222.: remote-server-error(502) XMPPError connecting to 113.19.87.196:5222.
    -- caused by: java.net.ConnectException: failed to connect to /113.19.87.196 (port 5222): connect failed: ETIMEDOUT (Connection timed out)"

    ReplyDelete
  20. The app is not running on android tab. It is showing this message: "Unfortunately, XMPP client has stopped working". I did not download the app from playstore... I used the source code given here.

    Can anyone suggest the reason for this error.

    ReplyDelete
  21. This app is working perfectly. In addition to this now I want to add offline messages, i did all the setting from server side. I am getting desired result as per setting done from server. Smack lib shows the log of offline message as the user gets login, but how can I get that message in Android? I tried to add packet listener with filter just after login(as per suggestion obtained from stackoverflow.com) but didnt worked at all. Please share some reference regarding Offline message manager and all that for obtaining offline messages.
    Thank You.

    ReplyDelete
  22. hello Hari, hope you are doing great,
    The app is working perfect with gmail service , I want to configure it on my own local host using ejabberd XMPP server ,
    may you please dictate from where I can find the process to accomplish this.
    thanks

    ReplyDelete
  23. Thank for your blog
    Its was my POC starting point, and now we are at development.
    Actually we are stuck at one point on Mobile App side, if you could help that would be great. Whenever their are connection issues on mobile like (data is stopped, no wifi etc ) the client is no more connected to Ejabbred but it stiff shows it as online and all the message sent are lost till ejabbred recognizes that the connection is lost

    ReplyDelete
  24. Thanks for the complete solution for the android chat client app .....This is the most useful solution available about this topics.Thanks a lot for helping the new learners.

    ReplyDelete
  25. what should i pass for third parameter named "service" for configuration...

    ReplyDelete
    Replies
    1. contact to me for real code. its working mail me sanjay.chourasia4@gmail.com

      Delete
  26. ontact to me for real code. its working mail me erick.ribeiro.16@gmail.com

    ReplyDelete

Fork me on GitHub