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

时间:2011-09-17 13:08:51

标签: android asmack

我正在为我的聊天应用程序使用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替代解决方案的人, 请帮我解决这个问题。

6 个答案:

答案 0 :(得分:7)

在谷歌搜索和搜索文档后,我得到了离线管理器以获取离线消息。

但是它不是在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);

希望它能帮助很多人找到离线消息的早期工作,因为我投入了更多的时间来解决它。

答案 1 :(得分:4)

用此替换您的代码。我已经使用此代码运行正常。

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;

}

答案 2 :(得分:1)

GTalkSMS是使用Asmack lib的每个基本操作的好例子,下面是我从GTalkSMS项目中获取离线消息的小示例代码。

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 :(得分:0)

尝试用此替换您的代码。

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

答案 4 :(得分:0)

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

在建立连接之前,应该将其称为

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

如果不打电话,你肯定会得到

答案 5 :(得分:0)

如果您不想自动获取离线消息(XEP-0013),请仅使用OfflineMessageManager。

否则只需将您的StanzaListener添加到连接并登录。

Action<ServiceAppointment>