Issue
Why i cant send images chat friend? What is the wrong?if i will selected photo my galery just sending text not image. i will send image but showing encoded image text. how to show on imageview.is the problem adapter?I implement picasso and glide but i dont use
Chat activitiy
public class ChatActivity extends BaseActivity {
private ActivityChatBinding binding;
private User receiverUser;
private List<ChatMessage> chatMessages;
private ChatAdapter chatAdapter;
private PreferenceManager preferenceManager;
private FirebaseFirestore database;
private String conversionId=null;
private Boolean isReceiverAvailable=false;
private String encodedImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding=ActivityChatBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setListeners();
loadReceiverDetails();
init();
listenMessages();
}
private void setListeners(){
binding.imageBack.setOnClickListener(v -> onBackPressed());
binding.layoutSend.setOnClickListener(v -> sendMessage());
binding.layoutSendPic.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
pickImage.launch(intent);
});
}
private void init(){
preferenceManager=new PreferenceManager(getApplicationContext());
chatMessages=new ArrayList<>();
chatAdapter=new ChatAdapter(
chatMessages,
getBitmapFromEncodedString(receiverUser.image),
preferenceManager.getString(Constants.KEY_USER_ID)
);
binding.chatRecyclerView.setAdapter(chatAdapter);
database=FirebaseFirestore.getInstance();
}
private String encodeImage(Bitmap bitmap){
int previewWidth=150;
int previewHeight=bitmap.getHeight()*previewWidth/ bitmap.getWidth();
Bitmap previewBitmap = Bitmap.createScaledBitmap(bitmap,previewWidth,previewHeight,false);
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
previewBitmap.compress(Bitmap.CompressFormat.JPEG,50,byteArrayOutputStream);
byte[] bytes=byteArrayOutputStream.toByteArray();
return Base64.encodeToString(bytes,Base64.DEFAULT);
}
private final ActivityResultLauncher<Intent> pickImage=registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode()==RESULT_OK){
if (result.getData()!=null){
Uri imageuri=result.getData().getData();
try{
InputStream inputStream= getContentResolver().openInputStream(imageuri);
Bitmap bitmap= BitmapFactory.decodeStream(inputStream);
encodedImage=encodeImage(bitmap);
sendPic();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
}
);
private void sendPic(){
HashMap<String,Object>message=new HashMap<>();
message.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID));
message.put(Constants.KEY_RECEIVER_ID,receiverUser.id);
message.put(Constants.KEY_TIMESTAMP,new Date());
message.put(Constants.KEY_MESSAGE,encodedImage);
message.put("type","image");
database.collection(Constants.KEY_COLLECTION_CHAT).add(message);
if (conversionId!=null){
updateConversion("photo");
}else{
HashMap<String,Object>conversion =new HashMap<>();
conversion.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID));
conversion.put(Constants.KEY_SENDER_NAME,preferenceManager.getString(Constants.KEY_NAME));
conversion.put(Constants.KEY_SENDER_IMAGE,preferenceManager.getString(Constants.KEY_IMAGE));
conversion.put(Constants.KEY_RECEIVER_ID,receiverUser.id);
conversion.put(Constants.KEY_RECEIVER_NAME,receiverUser.name);
conversion.put(Constants.KEY_RECEIVER_IMAGE,receiverUser.image);
conversion.put(Constants.KEY_LAST_MESSAGE,encodedImage);
conversion.put(Constants.KEY_TIMESTAMP,new Date());
addConversion(conversion);
}
}
private void sendMessage(){
HashMap<String, Object> message=new HashMap<>();
message.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID));
message.put(Constants.KEY_RECEIVER_ID,receiverUser.id);
message.put(Constants.KEY_MESSAGE,binding.inputMessage.getText().toString());
message.put(Constants.KEY_TIMESTAMP,new Date());
database.collection(Constants.KEY_COLLECTION_CHAT).add(message);
if (conversionId!=null){
updateConversion(binding.inputMessage.getText().toString());
}else {
HashMap<String,Object>conversion =new HashMap<>();
conversion.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID));
conversion.put(Constants.KEY_SENDER_NAME,preferenceManager.getString(Constants.KEY_NAME));
conversion.put(Constants.KEY_SENDER_IMAGE,preferenceManager.getString(Constants.KEY_IMAGE));
conversion.put(Constants.KEY_RECEIVER_ID,receiverUser.id);
conversion.put(Constants.KEY_RECEIVER_NAME,receiverUser.name);
conversion.put(Constants.KEY_RECEIVER_IMAGE,receiverUser.image);
conversion.put(Constants.KEY_LAST_MESSAGE,binding.inputMessage.getText().toString());
conversion.put(Constants.KEY_TIMESTAMP,new Date());
addConversion(conversion);
}
binding.inputMessage.setText(null);
}
private void listenAvailabilityReceiver(){
database.collection(Constants.KEY_COLLECTION_USERS).document(
receiverUser.id
).addSnapshotListener(ChatActivity.this,(value, error) -> {
if (error!=null){
return;
}
if (value!=null){
if (value.getLong(Constants.KEY_AVAILABILITY)!=null){
int availability= Objects.requireNonNull(
value.getLong(Constants.KEY_AVAILABILITY)
).intValue();
isReceiverAvailable=availability==1;
}
}
if (isReceiverAvailable){
binding.textAvailability.setVisibility(View.VISIBLE);
}else{
binding.textAvailability.setVisibility(View.GONE);
}
});
}
private void listenMessages(){
database.collection(Constants.KEY_COLLECTION_CHAT)
.whereEqualTo(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID))
.whereEqualTo(Constants.KEY_RECEIVER_ID,receiverUser.id)
.addSnapshotListener(eventListener);
database.collection(Constants.KEY_COLLECTION_CHAT)
.whereEqualTo(Constants.KEY_SENDER_ID,receiverUser.id)
.whereEqualTo(Constants.KEY_RECEIVER_ID,preferenceManager.getString(Constants.KEY_USER_ID))
.addSnapshotListener(eventListener);
}
@SuppressLint({"NotifyDataSetChanged", "NewApi"})
private final EventListener<QuerySnapshot> eventListener=(value, error)->{
if (error!=null){
return;
}
if (value!=null) {
int count = chatMessages.size();
for (DocumentChange documentChange : value.getDocumentChanges()) {
if (documentChange.getType() == DocumentChange.Type.ADDED) {
ChatMessage chatMessage = new ChatMessage();
chatMessage.senderId = documentChange.getDocument().getString(Constants.KEY_SENDER_ID);
chatMessage.receiverId = documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID);
chatMessage.message = documentChange.getDocument().getString(Constants.KEY_MESSAGE);
chatMessage.dateTime = getReadableDateTime(documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP));
chatMessage.dateObject =documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP);
chatMessages.add(chatMessage);
}
}
Collections.sort(chatMessages, Comparator.comparing(o -> o.dateObject));
if (count==0){
chatAdapter.notifyDataSetChanged();
}else{
chatAdapter.notifyItemRangeInserted(chatMessages.size(),chatMessages.size());
binding.chatRecyclerView.smoothScrollToPosition(chatMessages.size()-1);
}
binding.chatRecyclerView.setVisibility(View.VISIBLE);
}
binding.progressBar.setVisibility(View.GONE);
if (conversionId==null){
checkForConversion();
}
};
private Bitmap getBitmapFromEncodedString(String encodedImage){
byte[] bytes= Base64.decode(encodedImage,Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes,0,bytes.length);
}
private void loadReceiverDetails(){
receiverUser=(User) getIntent().getSerializableExtra(Constants.KEY_USER);
binding.textName.setText(receiverUser.name);
}
private String getReadableDateTime(Date date){
return new SimpleDateFormat("MMMM dd,yyyy- hh:mm a", Locale.getDefault()).format(date);
}
private void addConversion(HashMap<String,Object>conversion){
database.collection(Constants.KEY_COLLECTION_CONVERSATIONS)
.add(conversion)
.addOnSuccessListener(documentReference -> conversionId=documentReference.getId());
}
private void updateConversion(String message){
DocumentReference documentReference=
database.collection(Constants.KEY_COLLECTION_CONVERSATIONS).document(conversionId);
documentReference.update(
Constants.KEY_LAST_MESSAGE,message,
Constants.KEY_TIMESTAMP,new Date()
);
}
private void checkForConversion(){
if (chatMessages.size()!=0){
checkForConversionRemotely(
preferenceManager.getString(Constants.KEY_USER_ID),
receiverUser.id
);
checkForConversionRemotely(
receiverUser.id,
preferenceManager.getString(Constants.KEY_USER_ID)
);
}
}
private void checkForConversionRemotely(String senderId,String receiverId){
database.collection(Constants.KEY_COLLECTION_CONVERSATIONS)
.whereEqualTo(Constants.KEY_SENDER_ID,senderId)
.whereEqualTo(Constants.KEY_RECEIVER_ID,receiverId)
.get()
.addOnCompleteListener(conversionOnCompleteListener);
}
private final OnCompleteListener<QuerySnapshot> conversionOnCompleteListener=task ->{
if (task.isSuccessful()&&task.getResult()!=null&&task.getResult().getDocuments().size()>0){
DocumentSnapshot documentSnapshot=task.getResult().getDocuments().get(0);
conversionId=documentSnapshot.getId();
}
};
@Override
protected void onResume() {
super.onResume();
listenAvailabilityReceiver();
}
}
Chat Adapter
package com.example.chat.adapters;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.chat.databinding.ItemContainerReceivedMessageBinding;
import com.example.chat.databinding.ItemContainerSentMessageBinding;
import com.example.chat.models.ChatMessage;
import java.util.List;
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<ChatMessage> chatMessages;
private final Bitmap receiverProfileImage;
private final String senderId;
public static final int VIEW_TYPE_SENT=1;
public static final int VIEW_TYPE_RECEIVED=2;
public ChatAdapter(List<ChatMessage> chatMessages, Bitmap receiverProfileImage, String senderId) {
this.chatMessages = chatMessages;
this.receiverProfileImage = receiverProfileImage;
this.senderId = senderId;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType==VIEW_TYPE_SENT){
return new SentMessageViewHolder(
ItemContainerSentMessageBinding.inflate(
LayoutInflater.from(parent.getContext()),
parent,
false
)
);
}else{
return new ReceivedMessageViewHolder(
ItemContainerReceivedMessageBinding.inflate(
LayoutInflater.from(parent.getContext()),
parent,
false
)
);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position)==VIEW_TYPE_SENT){
((SentMessageViewHolder)holder).setData(chatMessages.get(position));
}else{
((ReceivedMessageViewHolder)holder).setData(chatMessages.get(position),receiverProfileImage);
}
}
@Override
public int getItemCount() {
return chatMessages.size();
}
@Override
public int getItemViewType(int position) {
if(chatMessages .get(position).senderId.equals(senderId)){
return VIEW_TYPE_SENT;
}else {
return VIEW_TYPE_RECEIVED;
}
}
static class SentMessageViewHolder extends RecyclerView.ViewHolder{
private final ItemContainerSentMessageBinding binding;
SentMessageViewHolder(ItemContainerSentMessageBinding itemContainerSentMessageBinding){
super(itemContainerSentMessageBinding.getRoot());
binding=itemContainerSentMessageBinding;
}
void setData(ChatMessage chatMessage){
binding.textSentMessage.setText(chatMessage.message);
binding.textDatetime.setText(chatMessage.dateTime);
}
}
static class ReceivedMessageViewHolder extends RecyclerView.ViewHolder{
private final ItemContainerReceivedMessageBinding binding;
ReceivedMessageViewHolder(ItemContainerReceivedMessageBinding itemContainerReceivedMessageBinding){
super(itemContainerReceivedMessageBinding.getRoot());
binding=itemContainerReceivedMessageBinding;
}
void setData(ChatMessage chatMessage,Bitmap receiverProfileImage){
binding.textDatetime.setText(chatMessage.dateTime);
binding.imageProfile.setImageBitmap(receiverProfileImage);
}
}
}
item_container_sent_messages.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="4dp">
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/friendsImage"
app:riv_oval="true"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@color/white"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="@id/textSentMessage"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="@+id/textSentMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:background="@drawable/background_sent_message"
android:padding="12dp"
android:paddingStart="12dp"
android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="8dp"
app:layout_constraintWidth_max="wrap"
android:textColor="@color/white"
android:textSize="13sp"
app:layout_constraintEnd_toStartOf="@id/friendsImage"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.75"/>
<ImageView
android:id="@+id/sendPicture"
android:visibility="invisible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:padding="12dp"
android:paddingStart="12dp"
android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="8dp"
app:layout_constraintWidth_max="wrap"
android:textColor="@color/white"
android:textSize="13sp"
app:layout_constraintEnd_toStartOf="@id/friendsImage"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.75"/>
<TextView
android:id="@+id/textDatetime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:textColor="@color/gray"
android:textSize="8sp"
app:layout_constraintEnd_toEndOf="@id/textSentMessage"
app:layout_constraintTop_toBottomOf="@id/textSentMessage"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Solution
Use any third-party website(base64 to jpg) to confirm if the receiverUser.image
is resulting in the correct image or not. As for me, everything looks good in your code except this line.
Answered By - Abdullah Javed
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.