Question

I am using asmack library for my chat application.I am using below described code for getting messagecount:

ServiceDiscoveryManager manager = ServiceDiscoveryManager.getInstanceFor(connection);
                 DiscoverInfo info = manager.discoverInfo(null,"http://jabber.org/protocol/offline");
                    Form extendedInfo = Form.getFormFrom(info);
                    if (extendedInfo != null) {
                        String value = extendedInfo.getField("number_of_messages").getValues().next();
                        Log.e(TAG, "offline message"+value);


                    }

But i got exception as described below:

09-14 16:11:32.892: ERROR/AndroidRuntime(498):     at com.datingapps.breaktheice.SigninScreen.coonectToChat(SigninScreen.java:393)
09-14 16:35:20.611: WARN/System.err(538): java.lang.ClassCastException: org.jivesoftware.smack.util.PacketParserUtils$2
09-14 16:35:20.811: WARN/System.err(538):     at org.jivesoftware.smackx.ServiceDiscoveryManager.discoverInfo(ServiceDiscoveryManager.java:608)
09-14 16:35:20.811: WARN/System.err(538):     at com.datingapps.breaktheice.Chat$connectionTask.doInBackground(Chat.java:286)
09-14 16:35:20.811: WARN/System.err(538):     at com.datingapps.breaktheice.Chat$connectionTask.doInBackground(Chat.java:1)
09-14 16:35:20.811: WARN/System.err(538):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-14 16:35:20.811: WARN/System.err(538):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
09-14 16:35:20.821: WARN/System.err(538):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
09-14 16:35:20.821: WARN/System.err(538):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
09-14 16:35:20.821: WARN/System.err(538):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
09-14 16:35:20.821: WARN/System.err(538):     at java.lang.Thread.run(Thread.java:1096)

Anybody who have implemented it with asmack or have alternate solution with smack lib, Please help me to get out of this problem.

Was it helpful?

Solution

After Googling and searching in documentation,All i got that offlinemanager for getting offline messages.

But However it is not working in asmack or may be in smack.It always return 0 message.

Finally by seeing logs i found that each tie when i login i got lot of response from chat server which also contains offline message but with message tag not offline message tag.So I found finally

You can get offline messages from it by directly setting packet listener after just login .As i below described packet listener you have to implement after login method.

        PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
        this.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 + "]");
                    if (fromName.equalsIgnoreCase(matchUserJabberId
                            + "server name")) {


                        // }
                    }
                }
            }
        }, filter);

Hope it will help many to find a work around for offline message early as i invested more time to get it out.

OTHER TIPS

Replace your code with this . I have used this code its running fine.

public int offlinemessagecount(){
    try {

        ServiceDiscoveryManager manager = ServiceDiscoveryManager
                .getInstanceFor(connection);
        DiscoverInfo info = manager.discoverInfo(null,
                "http://jabber.org/protocol/offline");
        Form extendedInfo = Form.getFormFrom(info);
        if (extendedInfo != null) {
            String value = extendedInfo.getField("number_of_messages")
                    .getValues().next();

            return Integer.parseInt(value);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 0;

}

GTalkSMS is good example for every basic operation using Asmack lib , below is the small example code i took form GTalkSMS project to get offline messages.

public static void handleOfflineMessages(XMPPConnection connection, Context ctx)throws Exception {
        OfflineMessageManager offlineMessageManager = new OfflineMessageManager(connection);

        if (!offlineMessageManager.supportsFlexibleRetrieval()) {
            Log.d("Offline messages not supported");
            return;
        }

        if (offlineMessageManager.getMessageCount() == 0) {
            Log.d("No offline messages found on server");
        } else {
            List<Message> msgs = offlineMessageManager.getMessages();
            for (Message msg : msgs) {
                String fullJid = msg.getFrom();
                String bareJid = StringUtils.parseBareAddress(fullJid);
                String messageBody = msg.getBody();
                if (messageBody != null) {
                    Log.d("Retrieved offline message from " +messageBody);
                }
            }
            offlineMessageManager.deleteMessages();
        }
    }

Try replacing your code with this.

ProviderManager mgr = ProviderManager.getInstance();
mgr.addExtensionProvider(offline, http://jabber.org/protocol/offline, org.jivesoftware.smackx.packet.OfflineMessageInfo$Provider);
mgr.addIQProvider(offline, http://jabber.org/protocol/offline, org.jivesoftware.smackx.packet.OfflineMessageRequest$Provider);

OfflineMessageManager offMgr = new OfflineMessageManager(connection);
int numOffline = offMgr.getMessageCount();

Just checking, did you configure your smack providers?

Before establishing the connection, this should be called

SmackAndroid.init(mContext);    // this loads extension providers into aSmack
try { 
    conn.connect();
} catch (XMPPException e) {
    e.printStackTrace();
    // do something
}

Without calling this, you will definitely get

Only use OfflineMessageManager, if you don't want to get the offline messages automatically (XEP-0013).

Otherwise just add your StanzaListener to the connection and login.

    XMPPTCPConnectionConfiguration userBasicConfiguration = XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
            .setServiceName(SERVICE_NAME)
            .setHost(HOST_NAME)
            .setDebuggerEnabled(false)
            .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
            .setPort(PORT)
            .setUsernameAndPassword(userName, password)
            .build();
    AbstractXMPPConnection firstUserConnection = new XMPPTCPConnection(userBasicConfiguration);
    firstUserConnection.connect();
    StanzaFilter filter = new StanzaTypeFilter(Message.class);
    StanzaListener listener = stanza -> {
        System.out.println(stanza.toString());
    };
    firstUserConnection.addSyncStanzaListener(listener,filter);
    firstUserConnection.login();
    while (!Thread.currentThread().isInterrupted()){

    }
    firstUserConnection.disconnect();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top