我正在尝试创建一个聊天应用程序。因此,我想知道如何检查用户是否已看到该消息?我不知道如何实现它。
这是我的Firebase数据库结构
我遵循了一个教程,但是没有用。而且我也不明白逻辑。
以下是代码。
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();
});
有人对我如何实施有任何想法或建议吗?
答案 0 :(得分:0)
我希望这个答案对您有所帮助:
使用socket
向用户发送消息时,它处于seen = false
状态,并且从socket
收到消息后,便会收到一条通知(新消息)。 )会在Android中显示给用户,但仍处于seen = false
状态。当用户打开相关的聊天页面,并且在recyclerView
或linearLayout
或...中向用户显示收到的消息时,模式更改为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