在android中监听XMPP数据包
我发现了这个问题:Android 上的 XMPP 事件,答案解释了我的问题的解决方案我有。但我似乎无法弄清楚如何让 packetListener 工作。我尝试过 packetCollectors 和 packetListeners 但注意到似乎有效。
我不确定应该将数据包监听器放置在哪里。它应该进入服务的 onCreate() 方法,还是 onStartCommand() 中,或者应该放入每隔几秒运行一次的单独方法中?
我的困惑主要在于听众的概念。侦听器是否始终运行,并且一旦收到数据包就会触发?如何确保侦听器可以“看到”传入的数据包事件?
这是我目前尝试让它发挥作用的尝试:
public class XMPPService extends Service{
private static String TAG = "XMPPService";
XMPPConnection connection;
MultiUserChat muc;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate(){
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId){
ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
connection = new XMPPConnection(config);
try
{
connection.connect();
Log.i(TAG,"connected");
}
catch (XMPPException e)
{
Log.e(TAG, "Connection Issue: ", e);
}
try
{
connection.login("user", "password");
muc = new MultiUserChat(connection, "[email protected]");
muc.join("nick","password");
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
setConnection(connection);
}
catch (XMPPException e)
{
Log.e(TAG, "Connection Issue: ", e);
}
makeNotification("started");
return 1;
}
private void makeNotification(String msg){
Notification notification = new Notification(R.drawable.icon, msg, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MUCTestActivity.class), 2);
notification.setLatestEventInfo(this, "Title", msg, contentIntent);
NotificationManager nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nmgr.notify(123443, notification);
}
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
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(TAG, "Got text [" + message.getBody() + "] from [" + fromName + "]");
}
else
{
Log.i(TAG,"null");
}
}
}, filter);
}
}
}
I found this question: XMPP events on Android, and the answer explains a solution to the problem I am having. But I cannot seem to figure out how to get the packetListener to work. I have tried packetCollectors and packetListeners but noting seems to work.
I am unsure of where I should place the packet listeners. Should it go into the onCreate() method of the service, or in the onStartCommand(), or should it be put into a separate method that runs every few seconds?
My confusion is mostly with the concept of listeners. Is the listener always running, and will trigger as soon as a packet is received? And how do I make sure that the listener can 'see' the packet events coming in?
This is my current attempt at getting this to work:
public class XMPPService extends Service{
private static String TAG = "XMPPService";
XMPPConnection connection;
MultiUserChat muc;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate(){
super.onCreate();
}
public int onStartCommand(Intent intent, int flags, int startId){
ConnectionConfiguration config = new ConnectionConfiguration("jabber.org", 5222);
connection = new XMPPConnection(config);
try
{
connection.connect();
Log.i(TAG,"connected");
}
catch (XMPPException e)
{
Log.e(TAG, "Connection Issue: ", e);
}
try
{
connection.login("user", "password");
muc = new MultiUserChat(connection, "[email protected]");
muc.join("nick","password");
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
setConnection(connection);
}
catch (XMPPException e)
{
Log.e(TAG, "Connection Issue: ", e);
}
makeNotification("started");
return 1;
}
private void makeNotification(String msg){
Notification notification = new Notification(R.drawable.icon, msg, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MUCTestActivity.class), 2);
notification.setLatestEventInfo(this, "Title", msg, contentIntent);
NotificationManager nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nmgr.notify(123443, notification);
}
public void setConnection(XMPPConnection connection) {
this.connection = connection;
if (connection != null) {
// Add a packet listener to get messages sent to us
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
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(TAG, "Got text [" + message.getBody() + "] from [" + fromName + "]");
}
else
{
Log.i(TAG,"null");
}
}
}, filter);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PacketListener 部分看起来是正确的。它将附加到 smacks 连接(读取器线程),并在与过滤器匹配的数据包到达时由连接调用。你的概念是对的。
返回 START_STICKY(请在此处使用常量而不是值)也应该有助于保持服务并因此保持连接处于活动状态。
您在线看到连接的 JID 了吗?我不确定是否可以在不在 JID 名册中的情况下向 JID 发送消息。尝试在 smack 中启用调试:Connection.DEBUG_ENABLED=true。如果您有 asmack,所有调试消息都将进入 DBMS 日志。另外,模拟器和带断点的 eclipse 都是帮助您分析问题的强大工具。
The PacketListener part looks right. It will be attached to smacks connection (the reader thread) and invoked by the connection if a packet, which matches the filter, arrives. You got the concept right.
Returning START_STICKY (please use here the constant and not the value) should also help to keep the service and therefore the connection alive.
Do you see the JID of the connection online? I am not sure if one can always send messages to a JID without being in the roster of the JID. Try enabling debugging in smack: Connection.DEBUG_ENABLED=true. If you have asmack, all debug messages will go into DBMS log. Also the emulator and eclipse with breakpoints are powerful tools to help you analyze the problem.