I'm working on a chat application. But I couldn't group messages by date. I'm new to the Android studio and java. Can anyone tell me how to do?
My Codes:
MessageActivity.java
public class MessageActivity extends AppCompatActivity {
CircleImageView profile_image;
TextView username, status;
FirebaseUser fuser;
DatabaseReference reference;
ImageButton btn_send;
EditText text_send;
MessageAdapter messageAdapter;
List<Chat> mchat;
RecyclerView recyclerView;
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
profile_image = findViewById(R.id.profile_image);
username = findViewById(R.id.username);
status = findViewById(R.id.status);
btn_send = findViewById(R.id.btn_send);
text_send = findViewById(R.id.text_send);
intent = getIntent();
final String userid = intent.getStringExtra("userid");
fuser = FirebaseAuth.getInstance().getCurrentUser();
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String msg = text_send.getText().toString();
if (!msg.equals("")) {
sendMessage(fuser.getUid(), userid, msg);
} else {
text_send.setError(getResources().getText(R.string.you_cant_send_empty_message));
}
text_send.setText("");
}
});
reference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
reference.keepSynced(true);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
final User user = dataSnapshot.getValue(User.class);
final String fullNumber;
boolean showProfilePhoto;
boolean showLastSeen;
if (ContextCompat.checkSelfPermission(MessageActivity.this,
Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
if (contactExists(MessageActivity.this, user.getNumber())){
username.setText(getContactName(user.getNumber() ,MessageActivity.this));
}else{
fullNumber = ""+user.getArea_code()+""+user.getNumber();
username.setText(fullNumber);
}
} else {
fullNumber = ""+user.getArea_code()+""+user.getNumber();
username.setText(fullNumber);
}
if (user.getDisplayProfilePhoto().equals("everyone")) {
showProfilePhoto = true;
} else if (user.getDisplayProfilePhoto().equals("contacts")){
Everywhere everywhere = new Everywhere();
showProfilePhoto = everywhere.isContact(user.getId());
} else {
showProfilePhoto = false;
}
if (showProfilePhoto) {
if (user.getImageURL().equals("default")){
profile_image.setImageResource(R.drawable.profile_image);
} else {
Picasso.get().load(user.getImageURL()).networkPolicy(NetworkPolicy.OFFLINE).into(profile_image, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
Picasso.get().load(user.getImageURL()).into(profile_image);
}
});
}
}else {
profile_image.setImageResource(R.drawable.profile_image);
}
if (user.getDisplayLastSeen().equals("everyone")) {
showLastSeen = true;
} else if (user.getDisplayLastSeen().equals("contacts")){
Everywhere everywhere = new Everywhere();
showLastSeen = everywhere.isContact(user.getId());
} else {
showLastSeen = false;
}
if (showLastSeen) {
if (user.getStatus().equals("online")){
status.setText(getResources().getString(R.string.online));
} else {
String lastSeenTime = DateFormat.format("HH:mm", user.getLastSeen()).toString();
String lastSeenDate = DateFormat.format("dd/MM/yyyy HH:mm", user.getLastSeen()).toString();
String lastSeenDayMounthYear = DateFormat.format("dd/MM/yyyy", user.getLastSeen()).toString();
long today = System.currentTimeMillis();
String todayDayMounthYear = DateFormat.format("dd/MM/yyyy", today).toString();
if (lastSeenDayMounthYear.equals(todayDayMounthYear)) {
status.setText(getResources().getString(R.string.last_seen)+" "+getResources().getString(R.string.today_lower)+" "+lastSeenTime);
} else {
status.setText(getResources().getString(R.string.last_seen)+" "+lastSeenDate);
}
}
}
readMessages(fuser.getUid(), userid, user.getImageURL());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private boolean contactExists(Context _mContext, String number) {
if (number != null) {
Uri lookupUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String[] mPhoneNumberProjection = { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup.DISPLAY_NAME };
Cursor cur = _mContext.getContentResolver().query(lookupUri, mPhoneNumberProjection, null, null, null);
try {
assert cur != null;
if (cur.moveToFirst()) {
return true;
}
} finally {
if (cur != null)
cur.close();
}
return false;
} else {
return false;
}
}
public String getContactName(final String phoneNumber, Context context)
{
Uri uri=Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,Uri.encode(phoneNumber));
String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};
String contactName="";
Cursor cursor=context.getContentResolver().query(uri,projection,null,null,null);
if (cursor != null) {
if(cursor.moveToFirst()) {
contactName=cursor.getString(0);
}
cursor.close();
}
return contactName;
}
private void sendMessage(String sender, String receiver, String message) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
reference.keepSynced(true);
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
hashMap.put("date", System.currentTimeMillis());
reference.child("Chats").push().setValue(hashMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
if (databaseError == null){
databaseReference.keepSynced(true);
HashMap<String, Object> successMap = new HashMap<>();
successMap.put("sended", 1);
databaseReference.updateChildren(successMap);
}
}
});
}
private void readMessages(final String myid, final String userid, final String imageurl){
mchat = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Chats");
reference.keepSynced(true);
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mchat.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getReceiver().equals(myid) && chat.getSender().equals(userid) ||
chat.getReceiver().equals(userid) && chat.getSender().equals(myid)){
mchat.add(chat);
}
messageAdapter = new MessageAdapter(MessageActivity.this, mchat, imageurl);
recyclerView.setAdapter(messageAdapter);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
@Override
protected void onResume() {
super.onResume();
Everywhere everywhere = new Everywhere();
everywhere.status("online");
}
@Override
protected void onPause() {
super.onPause();
Everywhere everywhere = new Everywhere();
everywhere.status("offline");
}
}
MessageAdapter.java
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.ViewHolder> {
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
private Context mContext;
private List<Chat> mChat;
private String imageurl;
FirebaseUser fuser;
public MessageAdapter(Context mContext, List<Chat> mChat, String imageurl){
this.mChat = mChat;
this.mContext = mContext;
this.imageurl = imageurl;
}
@NonNull
@Override
public MessageAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_right, parent, false);
return new MessageAdapter.ViewHolder(view);
} else {
View view = LayoutInflater.from(mContext).inflate(R.layout.chat_item_left, parent, false);
return new MessageAdapter.ViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull final MessageAdapter.ViewHolder holder, int position) {
Chat chat = mChat.get(position);
holder.show_message.setText(chat.getMessage());
String message_date = DateFormat.format("HH:mm", chat.getDate()).toString();
holder.date.setText(message_date);
if (imageurl.equals("default")) {
holder.profile_image.setImageResource(R.drawable.profile_image);
} else {
Picasso.get().load(imageurl).networkPolicy(NetworkPolicy.OFFLINE).into(holder.profile_image, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
Picasso.get().load(imageurl).into(holder.profile_image);
}
});
}
}
@Override
public int getItemCount() {
return mChat.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView show_message, date;
public ImageView profile_image;
public ViewHolder(@NonNull View itemView) {
super(itemView);
show_message = itemView.findViewById(R.id.show_message);
date = itemView.findViewById(R.id.date);
profile_image = itemView.findViewById(R.id.profile_image);
}
}
@Override
public int getItemViewType(int position) {
fuser = FirebaseAuth.getInstance().getCurrentUser();
if (mChat.get(position).getSender().equals(fuser.getUid())) {
return MSG_TYPE_RIGHT;
} else {
return MSG_TYPE_LEFT;
}
}
}
Chat Model (getting chat data)
public class Chat {
private String sender;
private String receiver;
private String message;
private long date;
public Chat(String sender, String receiver, String message, long date) {
this.sender = sender;
this.receiver = receiver;
this.message = message;
this.date = date;
}
public Chat() {
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public long getDate() {
return date;
}
public void setDate(long date) {
this.date = date;
}
}
User Model (getting user data)
public class User {
private String id;
private String username;
private String imageURL;
private String number;
private String area_code;
private String about;
private String status;
private long lastSeen;
private String displayLastSeen;
private String displayProfilePhoto;
private String displayAbout;
private String displayStory;
public User(String id, String username, String imageURL, String number, String area_code, String about, String status, long lastSeen, String displayLastSeen, String displayProfilePhoto, String displayAbout, String displayStory) {
this.id = id;
this.username = username;
this.imageURL = imageURL;
this.number = number;
this.area_code = area_code;
this.about = about;
this.status = status;
this.lastSeen = lastSeen;
this.displayLastSeen = displayLastSeen;
this.displayProfilePhoto = displayProfilePhoto;
this.displayAbout = displayAbout;
this.displayStory = displayStory;
}
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getArea_code() {
return area_code;
}
public void setArea_code(String area_code) {
this.area_code = area_code;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public long getLastSeen() {
return lastSeen;
}
public void setLastSeen(long lastSeen) {
this.lastSeen = lastSeen;
}
public String getDisplayLastSeen() {
return displayLastSeen;
}
public void setDisplayLastSeen(String displayLastSeen) {
this.displayLastSeen = displayLastSeen;
}
public String getDisplayProfilePhoto() {
return displayProfilePhoto;
}
public void setDisplayProfilePhoto(String displayProfilePhoto) {
this.displayProfilePhoto = displayProfilePhoto;
}
public String getDisplayAbout() {
return displayAbout;
}
public void setDisplayAbout(String displayAbout) {
this.displayAbout = displayAbout;
}
public String getDisplayStory() {
return displayStory;
}
public void setDisplayStory(String displayStory) {
this.displayStory = displayStory;
}
}
chat_item_date.xml (displaying date, but i couldn't use it.)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/txtGroupDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="DATE"
android:padding="5dp"
android:background="@drawable/rounded_corner"
android:textColor="#707c83"/>
</RelativeLayout>
chat_item_left.xml (same with chat_item_right.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<RelativeLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
// android:layout_alignParentEnd="true"
// in chat_item_right.xml
>
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/profile_image"
android:visibility="gone"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/background_left"
// android:background="@drawable/background_right"
// in chat_item_right.xml
android:layout_alignParentStart="true"
// android:layout_alignParentEnd="true"
// in chat_item_right.xml
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
android:id="@+id/show_message"
android:maxWidth="255dp"
android:textSize="18sp"
android:padding="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/show_message"
android:layout_alignBottom="@id/show_message"
android:layout_marginBottom="5dp"
android:text="00:00"
android:id="@+id/date"
android:textSize="12sp"
/>
</RelativeLayout>
</RelativeLayout>