使用asmack库在android聊天应用程序中获取脱机消息

使用asmack库在android聊天应用程序中获取脱机消息,android,asmack,Android,Asmack,我正在为我的聊天应用程序使用asmack库。我正在使用下面描述的代码获取messagecount: ServiceDiscoveryManager manager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverInfo info = manager.discoverInfo(null,"http://jabber.org/protocol/offline");

我正在为我的聊天应用程序使用asmack库。我正在使用下面描述的代码获取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);


                    }
但我得到了如下所述的异常:

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)
使用asmack实现它或使用smack lib替代解决方案的任何人,
请帮助我解决此问题。

尝试用此代码替换您的代码

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();

在谷歌搜索文档后,我得到了一个离线管理器,用于获取离线消息

但是,它在asmack中不工作,或者可能在smack中。它总是返回0消息

最后,通过查看日志,我发现每次登录时,我都会收到来自聊天服务器的大量响应,该服务器也包含脱机消息,但带有消息标记而非脱机消息标记。因此,我最终找到了

您可以在登录后通过直接设置数据包侦听器从中获取脱机消息。正如我下面描述的数据包侦听器,您必须实现登录后的方法

        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);

希望它能帮助很多人尽早找到脱机消息的解决方案,因为我投入了更多的时间来发布它。

只是检查一下,您是否配置了smack提供商

在建立连接之前,应该调用此函数

SmackAndroid.init(mContext);    // this loads extension providers into aSmack
try { 
    conn.connect();
} catch (XMPPException e) {
    e.printStackTrace();
    // do something
}
如果不调用此函数,您肯定会得到

对于使用的每个基本操作都是一个很好的示例,下面是我从project中获取脱机消息的小示例代码

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();
        }
    }
publicstaticvoidhandleOfflineMessages(XMPPConnection连接,Context ctx)引发异常{
OfflineMessageManager OfflineMessageManager=新的OfflineMessageManager(连接);
如果(!offlineMessageManager.supportsFlexibleRetrieval()){
Log.d(“不支持脱机消息”);
返回;
}
如果(offlineMessageManager.getMessageCount()==0){
Log.d(“在服务器上找不到脱机邮件”);
}否则{
List msgs=offlineMessageManager.getMessages();
对于(消息msg:msgs){
字符串fullJid=msg.getFrom();
String bareJid=StringUtils.parseBareAddress(fullJid);
字符串messageBody=msg.getBody();
if(messageBody!=null){
Log.d(“从“+messageBody”检索到的脱机消息);
}
}
offlineMessageManager.deleteMessages();
}
}

用此代码替换您的代码。我用过这个代码,它运行得很好

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;

}

如果不想自动获取脱机消息(XEP-0013),请仅使用OfflineMessageManager

否则,只需将StanzaListener添加到连接并登录即可

    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();

感谢您的回复。我已经使用了您的代码,但现在我在logcat:09-20 07:25:07.600:WARN/System.err(1100):java.lang.ClassCastException:org.jivesoftware.smack.util.PacketParserUtils$2 09-20 07:25:07.600:WARN/System.err(1100):org.jivesoftware.smackx.servicescoverymanager.discoverInfo(ServiceDiscoveryManager.java:608)09-20 07:25:07.600:WARN/System.err(1100):位于org.jivesoftware.smackx.OfflineMessageManager.getMessageCount(OfflineMessageManager.java:92)我也有与chirag shahI相同的问题,我也收到了相同的类演员阵容异常,但我仍然没有收到脱机消息。@chirag。你能帮我吗?我正在寻找相同的问题。我已经检查了,我在日志猫中收到了脱机消息,但在我编写Notifi时,我无法将其通知给用户进程包部分的阳离子代码然后我注意到上面的代码在应用程序启动时甚至没有执行???并且在登录后,这段代码工作得非常好,但我也希望在脱机消息的情况下使用它。我怎么做?samei已经编写了与上面相同的代码,但仍然没有收到脱机消息。有时它将收到,但有些消息未收到。@BorntoWin请确保在登录前已添加数据包侦听器。登录后不久,将收到脱机消息。@chikka.anddeve与我的Implement相同,只是chante groupchat,但无法接收任何消息