Show me the code! – By Davanum Srinivas

Web Services, Apache, Websphere, IBM, etc.

Android – Just use Smack API for XMPP

with 53 comments

OUTDATED SAMPLE – Updated code is here:


http://davanum.wordpress.com/2008/12/29/updated-xmpp-client-for-android/

Using Smack XMPP API from Android

Once you get tired of the limitations of android’s built-in IMProvider and the corresponding API – IXmppSession and IXmppService, try the sample below. Inside the source/binary zip (bottom of this article) you will find a smack.jar that works with android. To build the jar yourself, You can download the Smack 3.0.4 sources from here and apply the patch here.

Here is a screen shot of the XMPP Settings Dialog.

1

Notes



  • For GTalk, use “gtalk.google.com” as host with port 5222. The service name is “gmail.com”

  • Don’t add “@gmail.com” in the user name, just the id will do

Here’s the code for the settings dialog


package org.apache.android.xmpp;

import android.app.Dialog;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;

/**
 * Gather the xmpp settings and create an XMPPConnection
 */
public class SettingsDialog extends Dialog implements android.view.View.OnClickListener {
    private XMPPClient xmppClient;

    public SettingsDialog(XMPPClient xmppClient) {
        super(xmppClient);
        this.xmppClient = xmppClient;
    }

    protected void onStart() {
        super.onStart();
        setContentView(R.layout.settings);
        getWindow().setFlags(4, 4);
        setTitle("XMPP Settings");
        Button ok = (Button) findViewById(R.id.ok);
        ok.setOnClickListener(this);
    }

    public void onClick(View v) {
        String host = getText(R.id.host);
        String port = getText(R.id.port);
        String service = getText(R.id.service);
        String username = getText(R.id.userid);
        String password = getText(R.id.password);

        // Create a connection
        ConnectionConfiguration connConfig =
                new ConnectionConfiguration(host, Integer.parseInt(port), service);
        XMPPConnection connection = new XMPPConnection(connConfig);

        try {
            connection.connect();
            Log.i("XMPPClient", "[SettingsDialog] Connected to " + connection.getHost());
        } catch (XMPPException ex) {
            Log.e("XMPPClient", "[SettingsDialog] Failed to connect to " + connection.getHost());
            xmppClient.setConnection(null);
        }
        try {
            connection.login(username, password);
            Log.i("XMPPClient", "Logged in as " + connection.getUser());

            // Set the status to available
            Presence presence = new Presence(Presence.Type.available);
            connection.sendPacket(presence);
            xmppClient.setConnection(connection);
        } catch (XMPPException ex) {
            Log.e("XMPPClient", "[SettingsDialog] Failed to log in as " + username);
            xmppClient.setConnection(null);
        }
        dismiss();
    }

    private String getText(int id) {
        EditText widget = (EditText) this.findViewById(id);
        return widget.getText().toString();
    }
}

Here is a screen shot of the main window.

1

Notes



  • In the Recipient field, make sure you add the “@gmail.com”, not just the user id

Here’s the code for the main activity


package org.apache.android.xmpp;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;

import java.util.ArrayList;

public class XMPPClient extends Activity {

    private ArrayList<String> messages = new ArrayList();
    private Handler mHandler = new Handler();
    private SettingsDialog mDialog;
    private EditText mRecipient;
    private EditText mSendText;
    private ListView mList;
    private XMPPConnection connection;

    /**
     * Called with the activity is first created.
     */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        mRecipient = (EditText) this.findViewById(R.id.recipient);
        mSendText = (EditText) this.findViewById(R.id.sendText);
        mList = (ListView) this.findViewById(R.id.listMessages);
        setListAdapter();

        // Dialog for getting the xmpp settings
        mDialog = new SettingsDialog(this);

        // Set a listener to show the settings dialog
        Button setup = (Button) this.findViewById(R.id.setup);
        setup.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                mHandler.post(new Runnable() {
                    public void run() {
                        mDialog.show();
                    }
                });
            }
        });

        // Set a listener to send a chat text message
        Button send = (Button) this.findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String to = mRecipient.getText().toString();
                String text = mSendText.getText().toString();

                Log.i("XMPPClient", "Sending text [" + text + "] to [" + to + "]");
                Message msg = new Message(to, Message.Type.chat);
                msg.setBody(text);
                connection.sendPacket(msg);
                messages.add(connection.getUser() + ":");
                messages.add(text);
                setListAdapter();
            }
        });
    }

    /**
     * Called by Settings dialog when a connection is establised with the XMPP server
     *
     * @param connection
     */
    public void setConnection
            (XMPPConnection
                    connection) {
        this.connection = connection;
        if (connection != null) {
            // Add a packet listener to get messages sent to us
            PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
            connection.addPacketListener(new PacketListener() {
                public void processPacket(Packet packet) {
                    Message message = (Message) packet;
                    if (message.getBody() != null) {
                        String fromName = StringUtils.parseBareAddress(message.getFrom());
                        Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
                        messages.add(fromName + ":");
                        messages.add(message.getBody());
                        // Add the incoming message to the list view
                        mHandler.post(new Runnable() {
                            public void run() {
                                setListAdapter();
                            }
                        });
                    }
                }
            }, filter);
        }
    }

    private void setListAdapter
            () {
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.multi_line_list_item,
                messages);
        mList.setAdapter(adapter);
    }
}

Download Source and APK from here – XMPPClient.zip

Written by Davanum Srinivas

December 31, 2007 at 9:36 am

Posted in Uncategorized

53 Responses

Subscribe to comments with RSS.

  1. Hey Srini,

    Great job! We are building a app for Android around XMPP and other Android services. this is cool stuff.

    Thanks,
    Sunil

    Sunil Vishnubhotla

    January 2, 2008 at 8:53 am

  2. Thanks Sunil,
    If anyone has trouble building the JARs, get kxml2 from here and place it in build/merge/ This should help.

    Blago

    January 3, 2008 at 1:23 pm

  3. Hi, Davanum,

    how did you get to compile 3rd party JAR file to Android platform? Could you list your steps? Thanks a lot in advance.

    Andrew

    Andrew

    January 4, 2008 at 3:32 pm

  4. The funny thing is that Android is using smack library underneath. You can see it by taking a look at XMPPService dex code.

    simeon

    January 6, 2008 at 4:34 pm

  5. [...] to watch that evolve as they flesh out the platform details. [edit: look like people are figuring out how to get around Google’s artificial limitations] It could be a very interesting platform for [...]

  6. Well, Android itself is using the smack library :)

    Russian Translit

    January 10, 2008 at 8:49 pm

  7. Have you had any issues with some of the smackx packages?

    It looks like its not loading the classes so things like ServiceDiscoverManager don’t work properly.

    Mike Ryan

    January 11, 2008 at 5:05 pm

  8. Great package! I tried to connect to a lokal openfire server but it failed. If I use your smack.jar together with android.jar outside the emulator it works fine. Are there some limitations (only connections to google talk server) inside the emulator?

    Markus

    January 16, 2008 at 3:06 am

  9. Found a workaround for the error descibed before: The Android platform seems not to use DNS entries in the hosts file (tested on Windows Vista and XP).

    Nether 127.0.0.1 nor “localhost” nor any other entry directing on the loopback address works. When I use the lokal address in my lokal network it’s runing fine and the connection can be established.

    Markus

    January 16, 2008 at 9:36 am

  10. Android – Just use Smack API for XMPP

    0
    vote

    Once you get tired of the limitations of android’s built-in IMProvider and the corresponding API – IXmppSession and IXmppService, try the sample below. Inside the source/binary zip (bottom of this article) you will find a smack.jar that work

    Go to Android

    January 17, 2008 at 4:44 am

  11. When I run this application, it gives me an error
    NullPointerException

    Natasha

    January 24, 2008 at 6:00 am

  12. Markus, what exactly do you mean by “When I use the lokal address in my lokal network it’s runing fine and the connection can be established.” ??

    Please help me if you know the answer. I understand redirecting the traffic from host port to guest port, but here the client is running on android, but it wont connect to the server- using the server name/hostname/ip address.

    Natasha

    January 30, 2008 at 6:14 am

  13. @Natasha: Just use the IP address of the computer where the xmpp server is running.

    If you are running xmpp server and android emulator on the same machine use the external IP address of the computer to connect. The loopback address (”localhost”, 127.0.0.1, etc.) does not work. I think android is resolving “localhost” to it self.

    Markus

    February 3, 2008 at 7:59 am

  14. Hi Guys, taking the XMPPClient.zip from above and running it through my emulator through Eclipse, I get a series of warnings like the following: W/dalvikvm(556): Link of class 'org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow$PopupListener' failed. The app comes up, yet testing sending messages I get nothing sent. I tried also adding to the project the smackx.jar file, but then I get errors about classes already being loaded. I’m using the following configs: talk.google.com 5222 gmail.com organic2@gmail.com . Can someone shed some some light on what might be going on here? Thanks.

    MikeO

    February 4, 2008 at 4:13 pm

  15. quick correction, my userid is just organic2, no @gmail.com, per the instructions above.

    MikeO

    February 4, 2008 at 4:15 pm

  16. Ok, update; I can send messages to GTalk, so I can have a conversation between a gtalk client and my android emulator. I would like to go phone to phone, or emulator to emulator in this case. I’ve scoured the user groups for this, anyone have an idea on how to do this?

    MikeO

    February 4, 2008 at 4:59 pm

  17. @MikeO: All smackx classes are compiled into the smack.jar above. That’s why you get the error messages after adding smackx.jar.

    The error message “W/dalvikvm(556): Link of class ‘org/jivesoftware/smackx/debugger/EnhancedDebuggerWindow$PopupListener’ failed.” is thrown because the debugger window requiring some java.awt classes not included in android is also compiled within.

    Based on Davanum’s patch I’ve compiled a new lightweight smack.jar where all these classes were removed. You can download the new jar file here.

    Markus

    February 9, 2008 at 8:36 am

  18. Markus, thank you for replying to my query. Really appreciate it.
    I tried using the local ip address of the machine where the OpenFire server is installed, but it gave me exception ‘No response from server’. Then I replaced the openfire server with gtalk and then with Jabberd 2 server, same result. And I’m sure the credentials are correct, logs in with a commercial client, but when I try from my Java client, just doesnt go past the ‘No response..’ error. And the code is exactly similar to the one above.

    If possible, please help.
    Thanks.

    Natasha

    February 13, 2008 at 6:48 am

  19. Natasha, do you get the error message “No response from the server.” or “No response from server.”? There are two different types of messages in the smack package.

    The first exception is thrown during the authentification process. Is your internet connection very slow? Smack waits only 5 seconds for a reply of the server and then the exception is thrown. Try to increase the packet reply timeout. The static method

    SmackConfiguration.setPacketReplyTimeout(15000);

    will set the timeout to 15 seconds. Set the timeout before connection.connect().

    Markus

    February 14, 2008 at 3:33 pm

  20. Hi, Could anyone please tell me how to use the above code, I mean step wise explaination of how to implement it?
    Please help me.

    Sonal

    February 15, 2008 at 8:26 am

  21. I am also encountering the null pointer exception. I built it using the new android sdk under eclipse. Launched the emulator OK. In the set up screen I set the host to talk.google.com port 5222, specified my gmail ID and password and pressed OK. After ‘thinking’ for a while the emulator came back with the chat window. In there I specified the recipient (another gmail account that’s logged into gtalk from a desktop, with full ‘____@gmail.com’ address), and tried to send it a message. When I clicked the “send” button I got a null pointer exception in org.apache.android.xmpp. From the desktop side, the gtalk application did not recognize that the emulator account was logged in, either.

    Please advice if possible. Thanks.

    anon8mizer

    February 21, 2008 at 4:28 am

  22. the question still remain from previous version of unofficial gtalk client, is this version capable to receiving text message from gtalk client? please advise

    enshrentko

    February 27, 2008 at 5:24 am

  23. i got the error “not connected to server” when trying to setting the connection, please advise

    enshrentko

    February 27, 2008 at 8:44 am

  24. And what about an Android-Jingle app.?

    Rodrigo

    March 8, 2008 at 11:37 am

  25. Could you try to update this sample for the latest android SDK please?

    Joseph Dung

    March 11, 2008 at 6:09 am

  26. Thanks! This is a great program.

    To Joseph Dung:

    The only thing you need to modify is the layout of the program. After you add “android” in front of each “id:”
    this program can run.

    Luke

    March 25, 2008 at 11:07 am

  27. Hello,

    thank you for this API porting, srinivas. It is at the heart of my entire project :)

    For anyone that might still be interrested in this API, have you guys tried out the example in the debugger ? And if you did, what were the results ?
    For me it works ok when i run the example, but when i try debugging it, it connects ok to the xmpp server (tried with talk.google.com and jabber.org). When stepping over

    “connection.login(username, password);”

    line the debugger waits for the 5 seconds default timeout of smack API and catches an xmppException. And it also says in its output window:

    “ERROR/OpenSSLSocketImpl(1234): SSL handshake failure (return code 0; error code 5; errno 0)”

    It makes no difference if I set a longer timeout. Just 5 minutes ago I have noticed that it can also connect from debugger if I press the Ok button again in the SettingsDialog form x-).
    Yes, if I “connect twice” from the debugger, I get my user connected and logged in to my server. lol ???

    Thanks

    kellogs

    March 31, 2008 at 7:13 pm

  28. Hi Davanum,
    I tried the source code for XXMP,its giving runtime error org/jivesoftware/smack/connectionConfiguration while trying to create ConnectionConfiguration connConfig =
    new ConnectionConfiguration(”talk.google.com”, 5222, “gmail.com”);
    Please let me know what can be possible error.

    anup tiwary

    April 2, 2008 at 12:27 am

  29. Hi there

    I get an XMPPException in Line 46 when trying to connect to talk.google.com (i.e. IP: 209.85.137.125). Any idea why?

    Greetz
    Graphity

    Graphity

    April 10, 2008 at 5:04 am

  30. Hi again

    I fired up my debugger, played around and found out that the exception comes from org.jivesoftware.smack.PacketRead Line 164 (it must be around there, I changes the code a little). The line says ‘throw new XMPPException(”Connection failed. No response from server.”);’ when connectionID == null.
    BUT, that connectionID is set in parsePackets(Thread) which is never called (or is it?).

    Any ideas what I can do?

    Graphity

    April 10, 2008 at 9:18 am

  31. Ok, I figured parsePackets(Thread) is called when init() is called. So do I get an XMPPException?

    Graphity

    April 11, 2008 at 3:41 am

  32. I am a beginner…. I dont know how to apply patch for the xmpp connection. I am getting Connenction configuration error.i.e, connection itself not getting established……. What is the error … Plz any one reply…
    Thanks.

    Gunaa

    April 22, 2008 at 8:00 am

  33. Please provide XMPPClient.zip with the patch

    Tinky

    September 5, 2008 at 1:52 am

  34. Hi. I hope this threat is already open. The XMPPClient.zip is no longer available. I build the client by my self, but i dont have the correct smack.jar file. And i don’t know how i can patch the original. Can anyone upload the XMPPClient.zip or patched smack.jar again?

    Bulldog

    September 18, 2008 at 4:09 am

  35. Hello,

    I have tried same code, i am getting error message on the program GMailSender.java, line is static {
    Security.addProvider(new org.apache.harmony.xnet.provider.jsse.JSSEProvider());
    }
    the error message is org.apache.harmony cannot be ressolved as type..

    is there any dependancies need to be installed to run an application.

    Thanks in Advance

    Regard’s
    Parasuraman.K

    Parasuram

    October 6, 2008 at 7:32 am

  36. Hey anyone has the updated zip file for SDK 1.0.

    indiabolbol

    October 17, 2008 at 10:35 pm

  37. I want to route(send) the received message to any another person.But can not do.when I creates a new chat to send message to another ID it is not working…..can anybody help me.

    Thanx in advanced.

    Vijendra Yadav

    November 13, 2008 at 3:38 am

  38. Dear all,
    The link (smack, xmppclient.zip) you provided is somehow invalid. Could you please post it again?

    Thanks a lot.

    Canh cut

    November 14, 2008 at 3:37 am

  39. Hi all,
    i have a problem sending a message with PacketExtension.
    I successfully patched the smack sources with the given diff-file.
    It works fine, to send a Message to different clients. But if i add a PacketExtension, the message don’t arrive the recipient.
    I tested the same example with my patched sources as normal java application. This works fine.
    So i think there is maybe more to patch, that it works on android.

    Does anyone have the same problems and have a solution?

    Thanks.

    Bulldog

    November 28, 2008 at 4:06 am

  40. @Bulldog,
    how do you patch the diff file to Smack?
    thnx

    I am having trouble with changing security features of android and i am guessing that it has something to do with /system/etc/security/ stuff.
    anybody has any idea?

    thanks

    mike

    November 29, 2008 at 7:13 pm

  41. @mike,
    the patching is very easy – and i din’t use a diff-tool.
    Just download the sources, open it in eclipse. Then open the three files and apply the changes from the diff-file.
    Then download the kxml2.jar and place it in build/merge.
    Run ant and its done.
    With the security problems u mentioned i can’t help u.

    @All
    Whats about my problem with the PacketExtension???

    Bulldog

    December 1, 2008 at 2:50 am

  42. Hi all,
    Thanks in advance .please send me the link for XMPPClient.zip .

    Rajesh

    December 10, 2008 at 6:49 am

  43. Hello
    Give me AndroidMenifest.xml for XMPPClient By Dvanum shrinivas

    Regards
    Jagtap

    Jagtap

    December 15, 2008 at 4:55 am

  44. I want AndroidManifest.xml for XMPPClient , so if anybody have it forward me jagtap@igloo360.com

    jagtap

    December 17, 2008 at 5:00 am

  45. My android can’t authenticate to my XMPP server. however, I could use IM program to login to my server.

    The log in the server showed the sever had accepted the connection from android, but there was no any authentication occuring.

    please help me
    PS. I still don’t understand how to apply the patch.

    Thanks
    Addion

    Addion

    December 18, 2008 at 5:32 am

  46. Hi,

    The the code example and smack.jar are missing. Can someone please upload them?

    I went over the patch but no joy, unless I’m missing something there are still a lot missing pieces…

    Cheers,
    Ilan

    Ilan

    December 19, 2008 at 2:09 am

  47. Can anyone send me a link to download the patched smack.jar file?
    Thanks in advance.

    earlence

    December 22, 2008 at 1:42 am

  48. [...] Android – Just use Smack API for XMPP « Show me the code! – By Davanum Srinivas [...]

  49. hi…………
    what is xmpp?
    in simple sentence

    sujisha

    March 9, 2009 at 5:15 am

  50. how to add the smack.jar file。

    jacen

    March 22, 2009 at 9:04 pm

  51. thanks, it works well,

    Mahsa

    March 31, 2009 at 7:41 am

  52. using OpenFire server as well, so far everything is smoothly working. Now it’s time to extend this bad boy! :)

    Thanks again.

    Logor

    April 22, 2009 at 11:46 pm


Leave a Reply