可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
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;
}
回答3:
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();
}
}
回答4:
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();
回答5:
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
回答6:
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();