Android-如何检查用户是否已看到消息

时间:2020-07-28 10:21:22

标签: android android-studio

我正在尝试创建一个聊天应用程序。因此,我想知道如何检查用户是否已看到该消息?我不知道如何实现它。

这是我的Firebase数据库结构

enter image description here

我遵循了一个教程,但是没有用。而且我也不明白逻辑。

以下是代码。

ValueEventListener seenListener;
private void seenMessage(String friendId) {
        db = FirebaseDatabase.getInstance().getReference().child("Message")
                .child(userId + " - " + friendId);
        
        seenListener = db.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if (snapshot.exists()) {
                    for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                        Chats chat = dataSnapshot.getValue(Chats.class);
                        if (chat.getReceiverID().equals(userId) && chat.getSenderId().equals(friendId)) {

                            HashMap<String, Object> hashMap = new HashMap<>();
                            hashMap.put("isSeen", true);
                            dataSnapshot.getRef().updateChildren(hashMap);

                        }
                    }
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

并且在适配器类中

        if (position == mList.size() - 1) {
        if (messages.isSeen()) {
            holder.seen.setText("Seen");
        } else {
            holder.seen.setText("Delivered");
        }
    } else {
        holder.seen.setVisibility(View.GONE);
    }

活动代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    toolbar.setTitle("");
    toolbar.setSubtitle("");

    intialiseVariables();

    recyclerView.setHasFixedSize(true);
    LinearLayoutManager linearLayout = new LinearLayoutManager(getApplicationContext());
    linearLayout.setStackFromEnd(true);
    recyclerView.setLayoutManager(linearLayout);

    user = FirebaseAuth.getInstance().getCurrentUser();
    userId = user.getUid();
    mList = new ArrayList<>();


    Intent intent = getIntent();
    name = intent.getStringExtra("name");
    friendPhoneNumber = intent.getStringExtra("firendPhoneNumber");
    username.setText(name);


    sendMedia = FirebaseStorage.getInstance().getReference().child(userId).child("Sent");
    databaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
    databaseReference.orderByChild("phoneNumber").equalTo(friendPhoneNumber).
            addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    for (DataSnapshot childSnapshot : snapshot.getChildren()) {
                        friendId = childSnapshot.getKey();
                        displayDetails(friendId);
                        readMessage(userId, friendId);
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {

                }
            });

    send.setOnClickListener(v -> {
        String message = editTextMessage.getText().toString();
        sendMessage(message, "text");
        genrateChatList();
    });
    chooseImage.setOnClickListener(v -> {
        if (isShown) {
            cardView.setVisibility(View.GONE);
            isShown = false;
        } else {
            cardView.setVisibility(View.VISIBLE);
            isShown = true;
        }
    });
    gallery.setOnClickListener(v -> {
        chooseImage();
    });

有人对我如何实施有任何想法或建议吗?

3 个答案:

答案 0 :(得分:0)

我希望这个答案对您有所帮助:

使用socket向用户发送消息时,它处于seen = false状态,并且从socket收到消息后,便会收到一条通知(新消息)。 )会在Android中显示给用户,但仍处于seen = false状态。当用户打开相关的聊天页面,并且在recyclerViewlinearLayout或...中向用户显示收到的消息时,模式更改为seen = true并通过以下方式发送到服务器socket

答案 1 :(得分:0)

您应该在收到消息时检查一下,该接收者是否处于活动状态或处于碎片状态? 如果为true,则接收方可以看到该消息。 而为用户加载的消息数据即消息由用户显示的含义,则必须看到它。

  socket.on("message", new Emitter.Listener() {
        @Override
        public void call(final Object... args) {
            if (getActivity() == null)
                return;
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    JSONObject data = (JSONObject) args[0];
                    try {
                        String senderID = data.getString("sender");
                        String receive_id = data.getString("receive_id");
                        String message = data.getString("message");
                        String senderNickname = data.getString("senderNickname");
                        String replybyid = data.getString("replybyid");
                        String replybytext = data.getString("replybytext");
                        String getid = data.getString("id");
                        String gettime_created_at = data.getString("time_created_at");
                        String getfile = data.getString("file");
                        String getdate = data.getString("time_created_at");
                        String getdocument = data.getString("document");
                        String getstatus = data.getString("status");
                        String getforward = data.getString("forward");
                        String profile = data.getString("profile");
                        if (!senderID.equals(Hawk.get("token_id")) && receive_id.equals(Hawk.get("token_id").toString())) {
                            SenderMessage message1 = new SenderMessage();
                            message1.setSender("0");
                            message1.setReceiver("1");
                            message1.setId(getid);
                            message1.setBody(new MyApplication().decrypt(message));
                            message1.setTime(gettime_created_at);
                            message1.setFile(getfile);
                            message1.setDocument(getdocument);
                            message1.setReplybyid(replybyid);
                            message1.setDate(getdate);
                            message1.setReplybytext(replybytext);
                            message1.setStatus(getstatus);
                            message1.setForward(getforward);
                            message1.setProfile(profile);
                            message1.setIsSeen(1);
                            if (receive_id.equals(Hawk.get("token_id"))) {
                                socket.emit("isseen", 1, senderID, receive_id);
                            }
                            senderMessages.add(0, message1);
                            Vibrator v = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
                            } else {
                                v.vibrate(500);
                            }
                        }

                        messageAdapter.setSelectedItem(0);
                        recyclerView.scrollToPosition(0);
                        messageAdapter.notifyDataSetChanged();

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    });

答案 2 :(得分:0)

好像您在更新数据库中的值,但从未在邮件适配器中更新isSeen

运行此命令后:

HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("isSeen", true);
dataSnapshot.getRef().updateChildren(hashMap);

正确的值在数据库中,但不会自动更新textview。因此,在更新数据库中的值之后,应该在消息的给定位置将更改通知给适配器。

消息在适配器中的位置一旦确定,就可以设置文本,并调用如下内容:

adapter.notifyItemChanged(position) // <-- position is the position of the message in the adapter