图像未发送给另一方 Android Studio java

Image doesn't send for other side Android Studio java

我有问题,因为我无法为另一方发送图像,它重复或发送空消息,但正常消息工作正常。 我尝试了很多教程并更改了一些 classes,但没有任何效果

这是我的回收站视图 class:

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"/>

并选择图片activity:

    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);
    }

listenMessages 方法:

    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);
    }

请帮忙谢谢!

问题


您实际上是在向适配器提供刚刚创建的 encodingImage,这就是为什么您会重复出现图像或根本没有图像的原因。

解决方案

这个解决方案有两个部分:

  1. 重新格式化方法及其参数
  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。更改代码以选择图像以发送图像

现在您在尝试发送图像方法时做了一件非常非常错误的事情。这个问题从您选择图像的地方开始。要解决它,请将其替换为以下代码:

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();
        }
    });

您现在还需要更改 encodeImage 方法!:

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;
    }