结对冲刺10
实现ChatAticity
1 package com.example.chatapptest.activities; 2 3 import androidx.appcompat.app.AppCompatActivity; 4 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapFactory; 7 import android.os.Bundle; 8 import android.util.Base64; 9 import android.view.View; 10 11 import com.example.chatapptest.R; 12 import com.example.chatapptest.adapters.ChatAdapter; 13 import com.example.chatapptest.databinding.ActivityChatBinding; 14 import com.example.chatapptest.models.ChatMessage; 15 import com.example.chatapptest.models.User; 16 import com.example.chatapptest.utilities.Constants; 17 import com.example.chatapptest.utilities.PreferenceManager; 18 import com.google.android.gms.tasks.OnCompleteListener; 19 import com.google.firebase.firestore.DocumentChange; 20 import com.google.firebase.firestore.DocumentReference; 21 import com.google.firebase.firestore.DocumentSnapshot; 22 import com.google.firebase.firestore.EventListener; 23 import com.google.firebase.firestore.FirebaseFirestore; 24 import com.google.firebase.firestore.QuerySnapshot; 25 26 import java.text.SimpleDateFormat; 27 import java.util.ArrayList; 28 import java.util.Collections; 29 import java.util.Date; 30 import java.util.HashMap; 31 import java.util.List; 32 import java.util.Locale; 33 import java.util.Objects; 34 35 public class ChatActivity extends BaseActivity { 36 37 private ActivityChatBinding binding; 38 private User receiverUser; 39 private List<ChatMessage> chatMessages; 40 private ChatAdapter chatAdapter; 41 private PreferenceManager preferenceManager; 42 private FirebaseFirestore database; 43 private String conversionId = null; 44 45 private Boolean isReceiverAvailable = false; 46 47 @Override 48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 binding = ActivityChatBinding.inflate(getLayoutInflater()); 51 setContentView(binding.getRoot()); 52 setListeners(); 53 loadReceiverDetails(); 54 init(); 55 listenMessages(); 56 } 57 58 private void init(){ 59 preferenceManager = new PreferenceManager(getApplicationContext()); 60 chatMessages = new ArrayList<>(); 61 chatAdapter = new ChatAdapter( 62 chatMessages, 63 getBitmapFromEncodedString(receiverUser.image), 64 preferenceManager.getString(Constants.KEY_USER_ID) 65 ); 66 binding.chatRecyclerView.setAdapter(chatAdapter); 67 database = FirebaseFirestore.getInstance(); 68 } 69 70 private void sendMessage(){ 71 HashMap<String,Object> message = new HashMap<>(); 72 message.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID)); 73 message.put(Constants.KEY_RECEIVER_ID,receiverUser.id); 74 message.put(Constants.KEY_MESSAGE,binding.inputMessage.getText().toString()); 75 message.put(Constants.KEY_TIMESTAMP,new Date()); 76 database.collection(Constants.KEY_COLLECTION_CHAT).add(message); 77 if(conversionId != null){ 78 updateConversion(binding.inputMessage.getText().toString()); 79 }else { 80 HashMap<String ,Object> conversion = new HashMap<>(); 81 conversion.put(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID)); 82 conversion.put(Constants.KEY_SENDER_NAME,preferenceManager.getString(Constants.KEY_NAME)); 83 conversion.put(Constants.KEY_SENDER_IMAGE,preferenceManager.getString(Constants.KEY_IMAGE)); 84 conversion.put(Constants.KEY_RECEIVER_ID,receiverUser.id); 85 conversion.put(Constants.KEY_RECEIVER_NAME,receiverUser.name); 86 conversion.put(Constants.KEY_RECEIVER_IMAGE,receiverUser.image); 87 conversion.put(Constants.KEY_LAST_MESSAGE,binding.inputMessage.getText().toString()); 88 conversion.put(Constants.KEY_TIMESTAMP,new Date()); 89 addConversion(conversion); 90 } 91 binding.inputMessage.setText(null); 92 } 93 94 private void listenAvailabilityOfReceiver(){ 95 database.collection(Constants.KEY_COLLECTION_USERS).document( 96 receiverUser.id 97 ).addSnapshotListener(ChatActivity.this,(value, error) -> { 98 if(error != null){ 99 return; 100 } 101 if(value != null){ 102 if(value.getLong(Constants.KEY_AVAILABILITY) != null){ 103 int availability = Objects.requireNonNull( 104 value.getLong(Constants.KEY_AVAILABILITY) 105 ).intValue(); 106 isReceiverAvailable = availability == 1; 107 } 108 } 109 if(isReceiverAvailable){ 110 binding.textAvailability.setVisibility(View.VISIBLE); 111 }else { 112 binding.textAvailability.setVisibility(View.GONE); 113 } 114 }); 115 } 116 117 private void listenMessages(){ 118 database.collection(Constants.KEY_COLLECTION_CHAT) 119 .whereEqualTo(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID)) 120 .whereEqualTo(Constants.KEY_RECEIVER_ID,receiverUser.id) 121 .addSnapshotListener(eventListener); 122 database.collection(Constants.KEY_COLLECTION_CHAT) 123 .whereEqualTo(Constants.KEY_SENDER_ID,receiverUser.id) 124 .whereEqualTo(Constants.KEY_RECEIVER_ID,preferenceManager.getString(Constants.KEY_USER_ID)) 125 .addSnapshotListener(eventListener); 126 } 127 private final EventListener<QuerySnapshot> eventListener = (value, error) -> { 128 if(error != null){ 129 return; 130 } 131 if(value != null){ 132 int count = chatMessages.size(); 133 for(DocumentChange documentChange : value.getDocumentChanges()){ 134 if(documentChange.getType() == DocumentChange.Type.ADDED){ 135 ChatMessage chatMessage = new ChatMessage(); 136 chatMessage.senderId = documentChange.getDocument().getString(Constants.KEY_SENDER_ID); 137 chatMessage.receiverId = documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID); 138 chatMessage.message = documentChange.getDocument().getString(Constants.KEY_MESSAGE); 139 chatMessage.dataTime = getReadableDateTime(documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP)); 140 chatMessage.dateObject = documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP); 141 chatMessages.add(chatMessage); 142 } 143 } 144 Collections.sort(chatMessages,(obj1,obj2) -> obj1.dateObject.compareTo(obj2.dateObject)); 145 if(count == 0){ 146 chatAdapter.notifyDataSetChanged(); 147 }else { 148 chatAdapter.notifyItemRangeInserted(chatMessages.size(),chatMessages.size()); 149 binding.chatRecyclerView.smoothScrollToPosition(chatMessages.size()-1); 150 } 151 binding.chatRecyclerView.setVisibility(View.VISIBLE); 152 } 153 binding.progressBar.setVisibility(View.GONE); 154 if(conversionId == null){ 155 checkForConversion(); 156 } 157 }; 158 159 private Bitmap getBitmapFromEncodedString(String encodedImage){ 160 byte[] bytes = Base64.decode(encodedImage,Base64.DEFAULT); 161 return BitmapFactory.decodeByteArray(bytes,0, bytes.length); 162 } 163 164 private void loadReceiverDetails(){ 165 receiverUser = (User) getIntent().getSerializableExtra(Constants.KEY_USER); 166 binding.textName.setText(receiverUser.name); 167 } 168 169 private void setListeners(){ 170 binding.imageBack.setOnClickListener(v -> onBackPressed()); 171 binding.layoutSend.setOnClickListener(v -> sendMessage()); 172 } 173 174 private String getReadableDateTime(Date date){ 175 return new SimpleDateFormat("MMMM dd, yyyy - hh:mm a", Locale.getDefault()).format(date); 176 } 177 178 private void updateConversion(String message){ 179 DocumentReference documentReference = 180 database.collection(Constants.KEY_COLLECTION_CONVERSATIONS).document(conversionId); 181 documentReference.update( 182 Constants.KEY_LAST_MESSAGE,message, 183 Constants.KEY_TIMESTAMP,new Date() 184 ); 185 } 186 187 private void addConversion(HashMap<String,Object> conversion){ 188 database.collection(Constants.KEY_COLLECTION_CONVERSATIONS) 189 .add(conversion) 190 .addOnSuccessListener(documentReference -> conversionId = documentReference.getId()); 191 } 192 193 private void checkForConversion(){ 194 if(chatMessages.size() != 0 ){ 195 checkForConversionRemotely( 196 preferenceManager.getString(Constants.KEY_USER_ID), 197 receiverUser.id 198 ); 199 checkForConversionRemotely( 200 receiverUser.id, 201 preferenceManager.getString(Constants.KEY_USER_ID) 202 ); 203 } 204 } 205 206 private void checkForConversionRemotely(String senderId,String receiverId){ 207 database.collection(Constants.KEY_COLLECTION_CONVERSATIONS) 208 .whereEqualTo(Constants.KEY_SENDER_ID,senderId) 209 .whereEqualTo(Constants.KEY_RECEIVER_ID,receiverId) 210 .get() 211 .addOnCompleteListener(conversionOnCompleteListener); 212 } 213 214 private final OnCompleteListener<QuerySnapshot> conversionOnCompleteListener = task -> { 215 if(task.isSuccessful() && task.getResult() != null && task.getResult().getDocuments().size() > 0){ 216 DocumentSnapshot documentSnapshot = task.getResult().getDocuments().get(0); 217 conversionId = documentSnapshot.getId(); 218 } 219 }; 220 221 @Override 222 protected void onResume() { 223 super.onResume(); 224 listenAvailabilityOfReceiver(); 225 } 226 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?