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>
CodePudding user response:
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.