0

これは私にはかなり奇妙です:私のプロジェクト(ちなみにYaximから派生しているので、Android用のチャットアプリです)では、messageeventlistenerを介して書き込み通知を実装しようとしています。通知イベントを受け取ります。リストビュー(別のクラスにあります)に表示するために、メッセージのようにデータベースに行を追加しています(テキストのみが「...」です)。カウンターを追加し、行がデータベースに適切に挿入されました(その後、実際のメッセージが表示されたときに行がデータベースから削除されます)。notifychangesも適切に呼び出されます。奇妙なことに、これらすべてにもかかわらず、行はリストビューに表示されません。手順を数行下に移動すると、通常のメッセージのパケットリスナーに挿入されます。しかし、packetlistenerはそうしないので、そのままにしておくことはできません。構成するすべての通知を適切に受信するため、その目的で常に機能するとは限りません。また、書き込み通知がデータベースに適切に挿入されている間、messageEventNotificationListener()にプロシージャを保持すると、実際のメッセージが到着しても書き込み通知メッセージは削除されません(iCountは増加し続けます)。プロシージャをpacketListenerに入れると、そうなります(したがって、メッセージがデータベースにプッシュされた後、iCountは0になります)

これはmessageeventlistenerです:

private void messageEventNotificationListener(){
    // Create a MessageEventManager
    if (mMessageEventManager == null)
        mMessageEventManager = new MessageEventManager(mXMPPConnection);
      // Add the listener that will react to the event notifications
    mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
          public void deliveredNotification(String from, String packetID) {
              Log.d(TAG, "The message has been delivered (" + from + ", " + packetID + ")");
          }

          public void displayedNotification(String from, String packetID) {
              Log.d(TAG, "The message has been displayed (" + from + ", " + packetID + ")");
          }

          public void composingNotification(String from, String packetID) {
              Log.d(TAG, "The message's receiver is composing a reply (" + from + ", " + packetID + ")");
              //controlla se l'utente non sta già scrivendo 
              String selection = ChatConstants.JID + " = '" + from + "' AND " +
                        ChatConstants.DELIVERY_STATUS + " = " + ChatConstants.DS_WRITING;

                Cursor cursor = mContentResolver.query(ChatProvider.CONTENT_URI,
                            new String[] { "count(" + ChatConstants._ID + ")" },
                            selection, null, null);
                cursor.moveToFirst();
                int iCount = cursor.getInt(0);
                //if (iCount == 0)
                //{
                    addChatMessageToDB(ChatConstants.INCOMING, from, "...", ChatConstants.DS_WRITING, System.currentTimeMillis(), packetID);

                //}

          }

          public void offlineNotification(String from, String packetID) {
              Log.d(TAG, "The message's receiver is offline (" + from + ", " + packetID + ")");
          }

          public void cancelledNotification(String from, String packetID) {
              Log.d(TAG, "The message's receiver cancelled composing a reply (" + from + ", " + packetID + ")");


          }
      });   

}

そしてここにpacketlistenerがあります:

private void registerMessageListener() {
    // do not register multiple packet listeners
    if (mPacketListener != null)
        mXMPPConnection.removePacketListener(mPacketListener);

    PacketTypeFilter filter = new PacketTypeFilter(Message.class);

    mPacketListener = new PacketListener() {
        public void processPacket(Packet packet) {
            try {
            if (packet instanceof Message) {
                Message msg = (Message) packet;
                String chatMessage = msg.getBody();

                DeliveryReceipt dr = (DeliveryReceipt)msg.getExtension("received", DeliveryReceipt.NAMESPACE);
                if (dr != null) {
                    Log.d(TAG, "got delivery receipt for " + dr.getId());
                    changeMessageDeliveryStatus(dr.getId(), ChatConstants.DS_DELIVERED);
                }


                if (chatMessage == null)
                    return;

                if (msg.getType() == Message.Type.error) {
                    chatMessage = "<Error> " + chatMessage;
                }

                long ts;
                DelayInfo timestamp = (DelayInfo)msg.getExtension("delay", "urn:xmpp:delay");
                if (timestamp == null)
                    timestamp = (DelayInfo)msg.getExtension("x", "jabber:x:delay");
                if (timestamp != null)
                    ts = timestamp.getStamp().getTime();
                else
                    ts = System.currentTimeMillis();

                String fromJID = getJabberID(msg.getFrom());

                //elimina il messaggio "writing" se esiste
                     deleteWritingChatMessageFromDB(fromJID);

                    if (msg.getExtension("request", DeliveryReceipt.NAMESPACE) != null) {
                        // got XEP-0184 request, send receipt
                        sendReceipt(msg.getFrom(), msg.getPacketID());
                    }

                    addChatMessageToDB(ChatConstants.INCOMING, fromJID, chatMessage, ChatConstants.DS_NEW, ts, msg.getPacketID());
                    mServiceCallBack.newMessage(fromJID, chatMessage);
                }
            }
            } catch (Exception e) {
                // SMACK silently discards exceptions dropped from processPacket :(
                Log.e(TAG, "failed to process packet:");
                e.printStackTrace();
            }

    };

    mXMPPConnection.addPacketListener(mPacketListener, filter);
}

最後に、挿入と削除のメソッド

private void addChatMessageToDB(int direction, String JID,
        String message, int delivery_status, long ts, String packetID) {
    ContentValues values = new ContentValues();

    values.put(ChatConstants.DIRECTION, direction);
    values.put(ChatConstants.JID, JID);
    values.put(ChatConstants.MESSAGE, message);
    values.put(ChatConstants.DELIVERY_STATUS, delivery_status);
    values.put(ChatConstants.DATE, ts);
    values.put(ChatConstants.PACKET_ID, packetID);

    Uri noteUri = mContentResolver.insert(ChatProvider.CONTENT_URI, values);
    //mContentResolver.notifyChange(noteUri, null);
}

private void deleteWritingChatMessageFromDB(String JID) {
    int count = mContentResolver.delete(ChatProvider.CONTENT_URI,
            ChatConstants.JID + " = ? AND " + ChatConstants.MESSAGE + " = ? AND " + ChatConstants.DELIVERY_STATUS + " = ?", new String[] { JID, "...", "3" });
    debugLog("deleteWritingChatMessageEntryFromDB: Deleted " + count + " entries");

}

これらのメソッドは両方ともChatProviderクラスに呼び出され、getContext()。getContentResolver()。notifyChange(url、null);で終了します。

4

1 に答える 1

0

問題が異なっていたことが判明しました。他の誰かが同じ問題で実行された場合に備えて、これを投稿します。メッセージは実際には db に挿入されましたが、packetlistener は jid のみを返しますが、messageeventlistener は最後にリソースを含む jid を返します。これは挿入前に削除する必要がありました。すると、メッセージがリストに表示されました。また、私が投稿したコードは、messageEvent を処理するには完全に正しくありません。リスナーは、packetListener 内から直接呼び出す必要があります。

于 2012-09-13T17:51:29.117 に答える