我有問題,因為我無法為對方發送影像,它重復或發送空訊息,但正常訊息作業正常。我嘗試了許多教程并更改了一些課程,但沒有任何效果
這是我的回收站視圖類:
public final class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<ChatMessage> messages;
private Bitmap profileImage;
private final String senderId;
private static final int VIEW_TYPE_SENT = 1;
private static final int VIEW_TYPE_RECEIVED = 2;
public void setReceiverProfileImage(Bitmap bitmap) {
this.profileImage = bitmap;
}
public ChatAdapter(List<ChatMessage> messages, Bitmap profileImage, String senderId) {
this.messages = messages;
this.profileImage = profileImage;
this.senderId = senderId;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return (viewType == VIEW_TYPE_SENT ? new SentMessageViewHolder(
ItemContainerSentMessageBinding.inflate(
LayoutInflater.from(parent.getContext()),
parent,
false)
) : 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(messages.get(position));
} else {
((ReceivedMessageViewHolder) holder).setData(messages.get(position), profileImage);
}
}
@Override
public int getItemCount() {
return messages.size();
}
@Override
public int getItemViewType(int position) {
return (messages.get(position).getSenderId().equals(senderId) ? VIEW_TYPE_SENT : VIEW_TYPE_RECEIVED);
}
public static class SentMessageViewHolder extends RecyclerView.ViewHolder {
private final ItemContainerSentMessageBinding binding;
public SentMessageViewHolder(ItemContainerSentMessageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void setData(ChatMessage message) {
binding.textMessage.setText(message.getMessage());
binding.textDateTime.setText(message.getDateTime());
binding.image.setImageBitmap(message.getImage());
}
}
public static class ReceivedMessageViewHolder extends RecyclerView.ViewHolder {
private final ItemContainerReceivedMessageBinding binding;
public ReceivedMessageViewHolder(ItemContainerReceivedMessageBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
void setData(ChatMessage message, Bitmap bitmap) {
binding.textMessage.setText(message.getMessage());
binding.textDateTime.setText(message.getDateTime());
if (bitmap != null) {
binding.imageProfile.setImageBitmap(bitmap);
}
binding.image.setImageBitmap(message.getImage());
}
}
}
這是收到的訊息:
<com.makeramen.roundedimageview.RoundedImageView
android:id="@ id/imageProfile"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/background_image"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="@id/textMessage"
app:layout_constraintStart_toStartOf="parent"
app:riv_oval="true"/>
<TextView
android:id="@ id/textMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp"
android:background="@drawable/background_received_message"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_constraintWidth_max="wrap"
android:textColor="@color/white"
android:textSize="13sp"
app:layout_constraintStart_toEndOf="@id/imageProfile"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.75"/>
<ImageView
android:id="@ id/image"
android:background="@drawable/background_sent_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_marginStart="4dp"
android:maxWidth="250dp"
android:maxHeight="250dp"
app:layout_constraintStart_toEndOf="@id/imageProfile"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@ id/textDateTime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="@color/secondary_text"
android:textSize="8sp"
app:layout_constraintStart_toStartOf="@id/textMessage"
app:layout_constraintTop_toBottomOf="@id/textMessage"/>
并選擇影像活動:
private final ActivityResultLauncher<Intent> pickImage = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() != RESULT_OK) return;
if (result.getData() == null) return;
Uri imageUri = result.getData().getData();
try {
InputStream inputStream = getContentResolver().openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
this.encodingImage = encodeImage(bitmap);
sendMessage();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
});
并在這里創建 ChatMessage 物件(eventListener):
private final EventListener<QuerySnapshot> eventListener = (value, error) -> {
if (error != null) {
return;
}
if (value != null) {
int count = messages.size();
for (DocumentChange documentChange : value.getDocumentChanges()) {
if (documentChange.getType() == DocumentChange.Type.ADDED) {
ChatMessage chatMessage = new ChatMessage(
documentChange.getDocument().getString(Constants.KEY_SENDER_ID),
documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID),
documentChange.getDocument().getString(Constants.KEY_MESSAGE),
getReadableDateTime(documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP)),
documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP)
);
if (!encodingImage.isEmpty()) {
byte[] decodedString = Base64.decode(encodingImage, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
chatMessage.setImage(decodedByte);
}
messages.add(chatMessage);
}
}
Collections.sort(messages, Comparator.comparing(ChatMessage::getDate));
if (count == 0) {
chatAdapter.notifyDataSetChanged();
} else {
chatAdapter.notifyItemRangeInserted(messages.size(), messages.size());
binding.chatRecyclerView.smoothScrollToPosition(messages.size() - 1);
}
binding.chatRecyclerView.setVisibility(View.VISIBLE);
}
binding.progressBar.setVisibility(View.GONE);
if (conversionId == null) checkForConversion();
};
發送訊息方法:
private void sendMessage() {
Map<String, Object> message = new HashMap<>();
message.put(Constants.KEY_SENDER_ID, preferenceManager.getString(Constants.KEY_USER_ID));
message.put(Constants.KEY_RECEIVER_ID, user.getId());
message.put(Constants.KEY_MESSAGE, binding.inputMessage.getText().toString());
if (!encodingImage.isEmpty()) {
message.put(Constants.KEY_IMAGE_MESSAGE, encodingImage);
}
message.put(Constants.KEY_TIMESTAMP, new Date());
db.collection(Constants.KEY_COLLECTION_CHAT).add(message);
if (conversionId != null) {
updateConversion(binding.inputMessage.getText().toString());
} else {
Map<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, user.getId());
conversion.put(Constants.KEY_RECEIVER_NAME, user.getName());
conversion.put(Constants.KEY_RECEIVER_IMAGE, user.getImage());
conversion.put(Constants.KEY_LAST_MESSAGE, binding.inputMessage.getText().toString());
conversion.put(Constants.KEY_TIMESTAMP, new Date());
addConversion(conversion);
}
if (!isReceiverAvaible) {
try {
JSONArray tokens = new JSONArray();
tokens.put(user.getToken());
JSONObject data = new JSONObject();
data.put(Constants.KEY_USER_ID, preferenceManager.getString(Constants.KEY_USER_ID));
data.put(Constants.KEY_NAME, preferenceManager.getString(Constants.KEY_NAME));
data.put(Constants.KEY_FCM_TOKEN, preferenceManager.getString(Constants.KEY_FCM_TOKEN));
data.put(Constants.KEY_MESSAGE, binding.inputMessage.getText().toString());
JSONObject body = new JSONObject();
body.put(Constants.REMOTE_MSG_DATA, data);
body.put(Constants.REMOTE_MSG_REGISTRATION_IDS, tokens);
sendNotification(body.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
binding.inputMessage.setText(null);
}
監聽訊息方法:
private void listenMessages() {
db.collection(Constants.KEY_COLLECTION_CHAT)
.whereEqualTo(Constants.KEY_SENDER_ID, preferenceManager.getString(Constants.KEY_USER_ID))
.whereEqualTo(Constants.KEY_RECEIVER_ID, user.getId())
.addSnapshotListener(eventListener);
db.collection(Constants.KEY_COLLECTION_CHAT)
.whereEqualTo(Constants.KEY_SENDER_ID, user.getId())
.whereEqualTo(Constants.KEY_RECEIVER_ID, preferenceManager.getString(Constants.KEY_USER_ID))
.addSnapshotListener(eventListener);
}
private String encodeImage(Bitmap bitmap) {
int previewWidth = 300;
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);
return Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
}
請幫忙,謝謝!
uj5u.com熱心網友回復:
問題
您實際上是在提供encodingImage剛剛創建的配接器,這就是為什么您會重復或根本沒有影像的原因。
解決方案
此解決方案有 2 個部分:
- 重新格式化方法及其引數
- 更改代碼以選擇影像以發送影像
開始吧 !
1.重新格式化方法及其引數
首先,您需要在sendMessage()方法中添加 1 個引數。它看起來像這樣:
private void sendMessage(String encodedImage) {
Map<String, Object> message = new HashMap<>();
message.put(Constants.KEY_SENDER_ID, preferenceManager.getString(Constants.KEY_USER_ID));
message.put(Constants.KEY_RECEIVER_ID, user.getId());
message.put(Constants.KEY_MESSAGE, binding.inputMessage.getText().toString());
message.put(Constants.KEY_IMAGE_MESSAGE, encodedImage);
message.put(Constants.KEY_TIMESTAMP, new Date());
db.collection(Constants.KEY_COLLECTION_CHAT).add(message);
if (conversionId != null) {
updateConversion(binding.inputMessage.getText().toString());
} else {
Map<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, user.getId());
conversion.put(Constants.KEY_RECEIVER_NAME, user.getName());
conversion.put(Constants.KEY_RECEIVER_IMAGE, user.getImage());
conversion.put(Constants.KEY_LAST_MESSAGE, binding.inputMessage.getText().toString());
conversion.put(Constants.KEY_TIMESTAMP, new Date());
addConversion(conversion);
}
if (!isReceiverAvaible) {
try {
JSONArray tokens = new JSONArray();
tokens.put(user.getToken());
JSONObject data = new JSONObject();
data.put(Constants.KEY_USER_ID, preferenceManager.getString(Constants.KEY_USER_ID));
data.put(Constants.KEY_NAME, preferenceManager.getString(Constants.KEY_NAME));
data.put(Constants.KEY_FCM_TOKEN, preferenceManager.getString(Constants.KEY_FCM_TOKEN));
data.put(Constants.KEY_MESSAGE, binding.inputMessage.getText().toString());
JSONObject body = new JSONObject();
body.put(Constants.REMOTE_MSG_DATA, data);
body.put(Constants.REMOTE_MSG_REGISTRATION_IDS, tokens);
sendNotification(body.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
binding.inputMessage.setText(null);
}
現在,在此之后,您需要更改eventListener物件。它看起來像這樣:
private final EventListener<QuerySnapshot> eventListener = (value, error) -> {
if (error != null) {
return;
}
if (value != null) {
int count = messages.size();
for (DocumentChange documentChange : value.getDocumentChanges()) {
if (documentChange.getType() == DocumentChange.Type.ADDED) {
ChatMessage chatMessage = new ChatMessage(
documentChange.getDocument().getString(Constants.KEY_SENDER_ID),
documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID),
documentChange.getDocument().getString(Constants.KEY_MESSAGE),
getReadableDateTime(documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP)),
documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP)
);
if (documentChange.getDocument().getString(Constants.KEY_IMAGE_MESSAGE) != null && !documentChange.getDocument().getString(Constants.KEY_IMAGE_MESSAGE).isEmpty()) {
byte[] decodedString = Base64.decode((documentChange.getDocument().getString(Constants.KEY_IMAGE_MESSAGE, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
chatMessage.setImage(decodedByte);
}
messages.add(chatMessage);
}
}
Collections.sort(messages, Comparator.comparing(ChatMessage::getDate));
if (count == 0) {
chatAdapter.notifyDataSetChanged();
} else {
chatAdapter.notifyItemRangeInserted(messages.size(), messages.size());
binding.chatRecyclerView.smoothScrollToPosition(messages.size() - 1);
}
binding.chatRecyclerView.setVisibility(View.VISIBLE);
}
binding.progressBar.setVisibility(View.GONE);
if (conversionId == null) checkForConversion();
};
2. Change the code to pick image for sending image
Now you are doing a very very wrong thing while trying to send an image method. This issue start's from the place where you are picking the image. To solve it, replace that with this code:
private final ActivityResultLauncher<Intent> pickImage = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() != RESULT_OK) return;
if (result.getData() == null) return;
Uri imageUri = result.getData().getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
sendMessage(encodeImage(bitmap));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
});
Also you need to change the encodeImage method now!:
private String encodeImage(Bitmap bitmap) {
int previewWidth = 300;
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);
String str = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
return str == null ? "" : str;
}
Tada! This must work now. If not, pls inform me!
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/451316.html
