在xmpp中处理数据包监听器

时间:2014-10-06 04:43:30

标签: android android-listview xmpp android-adapter

我正在尝试使用asmack api开发一个Android聊天应用程序,服务器是openfire。 我处于处理来自用户的传入消息并代表它们相应的用户聊天屏幕(即活动)的阶段。

为此,我开发了两项活动,即

public class ResultActivity extends Activity 
public class UserActivity extends Activity

resultactivity是一个维护名单存在信息的人,如在线,离开等等,所以这只是一个例子。

useractivity是与相应用户保持聊天列表的用户。此活动以ResultActivity中列表上的onclick事件开始。因此,根据结果活动中没有用户,这可以是多个。

因此,为了监听传入的数据包(即传入的消息),我在ResultActivity中添加了一个监听器,它将消息添加到全局arraylist中。

在结果活动中:

PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
MainActivity.connection.addPacketListener(receive_message, filter);

PacketListener receive_message = new PacketListener() {
    public void processPacket(Packet packet) {
        message = (Message) packet;
        String sender=null,body=null,sender_final=null;
        if (message.getBody() !=null) {
            Log.d("UA", "message from "+StringUtils.parseBareAddress(message.getFrom()));
            Log.d("UA", "message is "+message.getBody());
            sender = StringUtils.parseBareAddress(message.getFrom());
            sender_final=sender.substring(0, sender.indexOf('@'));
            body = message.getBody();

            Log.d("UA", "Sender : "+sender_final+" body : "+body);
            userMessage = new UserMessage("In", sender_final, body);
            userMessage_list.add(userMessage);

            userMessage_list.add(userMessage);

        }
    }
};

在全局消息列表中添加消息(即userMessage_list)后,我需要使用传入消息更新用户活动。 userMessage_list是在基本适配器扩展类的getview方法中用作数组的数组列表。

所以现在我需要使用notifydatasetchanged方法更新userActivity列表。

在UserActivity中:

private class UserActivityThread extends Thread {
    @Override
    public void run() { 
    UserActivity.this.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                 userAdapter.notifyDataSetChanged();
            }
        });
    }
}

那么如何在另一个活动中调用notifydatasetchanged方法。

我很想知道如何在whatsapp或任何聊天应用程序中处理这种情况。

1 个答案:

答案 0 :(得分:0)

我在聊天应用中使用ContentProvider类和CursorLoader解决了这个问题,每当某个URI有新记录时,它会自动得到通知。

在您的情况下,我建议您发布广播消息。包含ListView消息的班级将注册BroadcastReceiver,并且会收听可能的更新。每次在您的活动中触发BroadcastReceiver.onReceive时,请刷新适配器。

希望有所帮助:)

修改

如何实现这一目标:

  1. 在您的活动中创建一个BroadcastReceiver对象。

    BroadcastReceiver mReceiver;

  2. 编码您的广播接收器(例如,在您的onCreate上)

        mReceiver = new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            //extract our message from intent
            String extra= intent.getStringExtra("extra");
    
            Log.i("msg received: ", extra);
    
        }
    };
    
  3. 添加IntentFilter(在您的onResume中可能有效)

    IntentFilter intentFilter = new IntentFilter("com.myproject.myintentfilter");

  4. 4.1注册您的接收器

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        registerReceiver(mReceiver,intentFilter);
    }
    

    4.2取消注册您的接收器

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        this.unregisterReceiver(mReceiver);
    }
    
    1. 确保您的收件人会收到消息,并确认您的sendBroadcastIntentFilter匹配。
    2. 最后:

      Intent i = new Intent("com.myproject.myintentfilter").putExtra("extra", "This is a new value");
      this.sendBroadcast(i);
      

      编辑2

      如果在您的活动轮换期间收到消息(接收者未注册),我找到了2个我不太满意的解决方案,但它们有效。

      1. 在方向更改后重新加载您的列表视图,因为活动会自行销毁,您只需重新加载列表视图的信息,无论如何都应该显示您的新消息。

      2. 在您的活动中放置一个静态字段,每次收到消息时,将此变量设置为TRUE。如果您的broadcastReceiver触发,将该变量置为false,并且在更改方向后调用onResume / onCreate方法时,请检查静态变量并在变量为true时重新加载(重新加载ListView后将其置为false) )。