结对冲刺11

实现MainActivity

复制代码
  1 package com.example.chatapptest.activities;
  2 
  3 import androidx.appcompat.app.AppCompatActivity;
  4 
  5 import android.content.Intent;
  6 import android.graphics.Bitmap;
  7 import android.graphics.BitmapFactory;
  8 import android.os.Bundle;
  9 import android.util.Base64;
 10 import android.view.View;
 11 import android.widget.Toast;
 12 
 13 import com.example.chatapptest.adapters.RecentConversationsAdapter;
 14 import com.example.chatapptest.databinding.ActivityMainBinding;
 15 import com.example.chatapptest.listeners.ConversionListener;
 16 import com.example.chatapptest.models.ChatMessage;
 17 import com.example.chatapptest.models.User;
 18 import com.example.chatapptest.utilities.Constants;
 19 import com.example.chatapptest.utilities.PreferenceManager;
 20 import com.google.firebase.firestore.DocumentChange;
 21 import com.google.firebase.firestore.DocumentReference;
 22 import com.google.firebase.firestore.EventListener;
 23 import com.google.firebase.firestore.FieldValue;
 24 import com.google.firebase.firestore.FirebaseFirestore;
 25 import com.google.firebase.firestore.QuerySnapshot;
 26 import com.google.firebase.messaging.FirebaseMessaging;
 27 
 28 import java.util.ArrayList;
 29 import java.util.Collections;
 30 import java.util.HashMap;
 31 import java.util.List;
 32 
 33 public class MainActivity extends BaseActivity implements ConversionListener {
 34 
 35     private ActivityMainBinding binding;
 36     private PreferenceManager preferenceManager;
 37     private List<ChatMessage> conversations;
 38     private RecentConversationsAdapter conversationsAdapter;
 39     private FirebaseFirestore database;
 40 
 41     @Override
 42     protected void onCreate(Bundle savedInstanceState) {
 43         super.onCreate(savedInstanceState);
 44         binding = ActivityMainBinding.inflate(getLayoutInflater());
 45         setContentView(binding.getRoot());
 46         preferenceManager = new PreferenceManager(getApplicationContext());
 47         init();
 48         loadUserDetails();
 49         getToken();
 50         setListeners();
 51         listenConversations();
 52     }
 53 
 54     //这些初始化操作为后续的对话记录展示和管理奠定了基础
 55     private void init(){
 56         // 1. 创建一个存储最近对话数据的 ArrayList
 57         conversations = new ArrayList<>();
 58         // 2. 创建 RecentConversationsAdapter 对象,并传入 conversations 列表和当前对象(可能是 Activity 或 Fragment)作为参数
 59         conversationsAdapter = new RecentConversationsAdapter(conversations,this);
 60         // 3. 将 conversationsAdapter 设置为 conversationsRecyclerView 的适配器,用于在界面上显示最近的对话列表
 61         binding.conversationsRecyclerView.setAdapter(conversationsAdapter);
 62         // 4. 获取 Firebase Firestore 数据库的实例,以便在后续操作中使用该数据库
 63         database = FirebaseFirestore.getInstance();
 64     }
 65 
 66     //这些监听器的设置为用户的登录退出和聊天创建提供了交互入口
 67     private void setListeners(){
 68         // 1. 为 imageSignOut 图标设置点击监听器
 69         binding.imageSignOut.setOnClickListener(v -> signOut());
 70         // 2. 为 fabNewChat 浮动按钮设置点击监听器
 71         binding.fabNewChat.setOnClickListener(v -> {
 72             // 2.1 当点击浮动按钮时,启动 UsersActivity
 73             startActivity(new Intent(getApplicationContext(), UsersActivity.class));
 74         });
 75     }
 76 
 77     //这段代码的主要作用是从 SharedPreferences 中读取用户的名称和头像信息,并将其显示在界面上
 78     private void loadUserDetails(){
 79         // 1. 从 SharedPreferences 中获取用户名,并设置到 textName TextView 中
 80         binding.textName.setText(preferenceManager.getString(Constants.KEY_NAME));
 81         // 2. 从 SharedPreferences 中获取用户头像的 Base64 编码字符串
 82         byte[] bytes = Base64.decode(preferenceManager.getString(Constants.KEY_IMAGE),Base64.DEFAULT);
 83         // 3. 将 Base64 编码的字符串解码为字节数组
 84         Bitmap bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length);
 85         // 5. 将解码后的 Bitmap 图像设置到 imageProfile ImageView 中
 86         binding.imageProfile.setImageBitmap(bitmap);
 87     }
 88 
 89     //使用 showToast() 方法可以方便地在应用程序的各个地方显示 Toast 消息
 90     private void showToast(String message){
 91         // 使用 Toast.makeText() 方法创建一个新的 Toast 消息
 92         Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
 93     }
 94 
 95     //确保用户在使用聊天应用时,能够及时看到最新的对话信息
 96     private void listenConversations(){
 97         // 1. 监听发送方为当前用户的对话记录变化
 98         database.collection(Constants.KEY_COLLECTION_CONVERSATIONS)
 99                 .whereEqualTo(Constants.KEY_SENDER_ID,preferenceManager.getString(Constants.KEY_USER_ID))
100                 .addSnapshotListener(eventListener);
101         // 2. 监听接收方为当前用户的对话记录变化
102         database.collection(Constants.KEY_COLLECTION_CONVERSATIONS)
103                 .whereEqualTo(Constants.KEY_RECEIVER_ID,preferenceManager.getString(Constants.KEY_USER_ID))
104                 .addSnapshotListener(eventListener);
105     }
106 
107     //确保用户在使用聊天应用时,能够及时看到最新的对话信息。
108     private final EventListener<QuerySnapshot> eventListener = (value, error) -> {
109         // 1. 如果出现错误,直接返回
110         if(error != null){
111             return;
112         }
113         // 2. 如果有数据变化
114         if(value != null){
115             // 遍历数据变化的文档
116             for(DocumentChange documentChange : value.getDocumentChanges()){
117                 // 2.1 如果是新增文档
118                 if(documentChange.getType() == DocumentChange.Type.ADDED){
119                     // 获取发送方和接收方的 ID
120                     String senderId = documentChange.getDocument().getString(Constants.KEY_SENDER_ID);
121                     String receiverId = documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID);
122                     // 创建一个新的 ChatMessage 对象
123                     ChatMessage chatMessage = new ChatMessage();
124                     chatMessage.senderId = senderId;
125                     chatMessage.receiverId = receiverId;
126                     // 根据当前用户是发送方还是接收方,设置对话的头像、名称和 ID
127                     if(preferenceManager.getString(Constants.KEY_USER_ID).equals(senderId)){
128                         chatMessage.conversionImage = documentChange.getDocument().getString(Constants.KEY_RECEIVER_IMAGE);
129                         chatMessage.conversionName = documentChange.getDocument().getString(Constants.KEY_RECEIVER_NAME);
130                         chatMessage.conversionId = documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID);
131                     }else {
132                         chatMessage.conversionImage = documentChange.getDocument().getString(Constants.KEY_SENDER_IMAGE);
133                         chatMessage.conversionName = documentChange.getDocument().getString(Constants.KEY_SENDER_NAME);
134                         chatMessage.conversionId = documentChange.getDocument().getString(Constants.KEY_SENDER_ID);
135                     }
136                     // 设置最后一条消息和时间戳
137                     chatMessage.message = documentChange.getDocument().getString(Constants.KEY_LAST_MESSAGE);
138                     chatMessage.dateObject = documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP);
139                     // 将新的 ChatMessage 对象添加到 conversations 列表中
140                     conversations.add(chatMessage);
141                     // 2.2 如果是修改文档
142                 } else if (documentChange.getType() == DocumentChange.Type.MODIFIED) {
143                     // 遍历 conversations 列表,更新对应的消息和时间戳
144                     for(int i = 0;i<conversations.size();i++){
145                         String senderId = documentChange.getDocument().getString(Constants.KEY_SENDER_ID);
146                         String receiverId = documentChange.getDocument().getString(Constants.KEY_RECEIVER_ID);
147                         if(conversations.get(i).senderId.equals(senderId) && conversations.get(i).receiverId.equals(receiverId)){
148                             conversations.get(i).message = documentChange.getDocument().getString(Constants.KEY_LAST_MESSAGE);
149                             conversations.get(i).dateObject = documentChange.getDocument().getDate(Constants.KEY_TIMESTAMP);
150                             break;
151                         }
152                     }
153                 }
154             }
155             // 3. 将 conversations 列表按时间戳降序排序
156             Collections.sort(conversations,(obj1,obj2) -> obj2.dateObject.compareTo(obj1.dateObject));
157             // 4. 通知适配器数据发生变化,并滚动到列表顶部
158             conversationsAdapter.notifyDataSetChanged();
159             binding.conversationsRecyclerView.smoothScrollToPosition(0);
160             binding.conversationsRecyclerView.setVisibility(View.VISIBLE);
161             binding.progressBar.setVisibility(View.GONE);
162         }
163     };
164 
165     //这段代码是实现移动应用程序消息推送功能的一部分
166     private void getToken(){
167         // 1. 获取 Firebase 云消息推送服务的实例
168         FirebaseMessaging.getInstance().getToken().addOnSuccessListener(this::updateToken);
169     }
170 
171     //可以确保应用程序的消息推送功能能够正常工作,提高用户体验。
172     private void updateToken(String token){
173         // 1. 获取 Firestore 数据库的实例
174         FirebaseFirestore database = FirebaseFirestore.getInstance();
175         // 2. 获取当前用户在 Firestore 中的文档引用
176         DocumentReference documentReference =
177                 database.collection(Constants.KEY_COLLECTION_USERS).document(
178                         preferenceManager.getString(Constants.KEY_USER_ID)
179                 );
180         // 3. 更新当前用户文档中的 FCM 推送令牌字段
181         documentReference.update(Constants.KEY_FCM_TOKEN,token)
182                 // 4. 如果更新失败,显示 Toast 提示
183                 .addOnFailureListener(e -> showToast("Unable to update token"));
184     }
185 
186     private void signOut(){
187         // 1. 显示"正在登出..."的 Toast 提示
188         showToast("Signing out ...");
189         // 2. 获取 Firestore 数据库的实例
190         FirebaseFirestore database = FirebaseFirestore.getInstance();
191         // 3. 获取当前用户在 Firestore 中的文档引用
192         DocumentReference documentReference =
193                 database.collection(Constants.KEY_COLLECTION_USERS).document(
194                         preferenceManager.getString(Constants.KEY_USER_ID)
195                 );
196         // 4. 创建一个 HashMap 用于更新文档字段
197         HashMap<String,Object> updates = new HashMap<>();
198         // 5. 将 FCM 推送令牌字段设置为删除操作
199         updates.put(Constants.KEY_FCM_TOKEN, FieldValue.delete());
200         documentReference.update(updates)
201                 // 7. 如果更新成功
202                 .addOnSuccessListener(unused -> {
203                     // 7.1 清除 SharedPreferences 中保存的用户信息
204                     preferenceManager.clear();
205                     // 7.2 启动登录页面 Activity,并结束当前 Activity
206                     startActivity(new Intent(getApplicationContext(),SignInActivity.class));
207                     finish();
208                 })
209                 // 8. 如果更新失败
210                 .addOnFailureListener(e -> showToast("Unable to sign out"));
211     }
212 
213     //实现用户点击对话列表中的对话,快速进入聊天页面的功能
214     @Override
215     public void onConversionClicked(User user) {
216         // 1. 创建一个 Intent 对象,指向 ChatActivity 类
217         Intent intent = new Intent(getApplicationContext(), ChatActivity.class);
218         // 2. 将当前点击的 User 对象通过 Intent 的 extras 传递到 ChatActivity
219         intent.putExtra(Constants.KEY_USER,user);
220         // 3. 启动 ChatActivity
221         startActivity(intent);
222     }
223 }
复制代码

 

posted @   新晋软工小白  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示