Getting offline messages in android chat applicati

2020-06-06 04:48发布

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.

6条回答
劫难
2楼-- · 2020-06-06 05:21

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();
        }
    }
查看更多
我欲成王,谁敢阻挡
3楼-- · 2020-06-06 05:24

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();
查看更多
萌系小妹纸
4楼-- · 2020-06-06 05:25

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;

}
查看更多
疯言疯语
5楼-- · 2020-06-06 05:26

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.

查看更多
Explosion°爆炸
6楼-- · 2020-06-06 05:34

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();
查看更多
我只想做你的唯一
7楼-- · 2020-06-06 05:38

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

查看更多
登录 后发表回答