拍摄照片功能流程梳理 ======================================== 一、入口:ConversationActivity页面 ---------------------------------------- 包名:cn.wildfire.chat.kit.conversation.ConversationActivity 1. ConversationActivity包含ConversationFragment - ConversationActivity在afterViews()中创建并添加ConversationFragment - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationActivity.java 2. ConversationFragment包含ConversationInputPanel - ConversationFragment在onCreateView()中初始化ConversationInputPanel - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationFragment.java 二、点击右下角加号按钮 ---------------------------------------- 包名:cn.wildfire.chat.kit.conversation.ConversationInputPanel 1. 加号按钮控件:extImageView (R.id.extImageView) - 在bindViews()中绑定控件 - 设置点击监听器:extImageView.setOnClickListener(v -> onExtImageViewClick()) 2. onExtImageViewClick()方法处理点击事件 - 如果当前显示的是扩展面板,则隐藏并显示键盘 - 否则,显示扩展面板(showConversationExtension()) - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationInputPanel.java (338-349行) 三、显示扩展菜单 ---------------------------------------- 包名:cn.wildfire.chat.kit.conversation.ext.core.ConversationExtension 1. ConversationExtension管理所有扩展功能 - 在ConversationInputPanel的init()方法中创建 - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/core/ConversationExtension.java 2. 扩展菜单包含多个ConversationExt,其中ImageExt负责图片选择 - ImageExt类:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/ImageExt.java - ImageExt的iconResId()返回R.mipmap.ic_func_pic(照片图标) 四、点击照片选项 ---------------------------------------- 包名:cn.wildfire.chat.kit.conversation.ext.ImageExt 1. pickImage()方法被调用 - 使用@ExtContextMenuItem注解标记 - 方法签名:public void pickImage(View containerView, Conversation conversation) 2. 创建ImagePicker Intent - ImagePicker.picker().showCamera(true).enableMultiMode(9).buildPickIntent(activity) - showCamera(true)表示显示拍照选项 - enableMultiMode(9)表示最多选择9张图片 - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/ImageExt.java (38-43行) 3. 启动ImageGridActivity - startActivityForResult(intent, 100) - 同时发送TypingMessageContent(TYPING_CAMERA)表示正在使用相机 五、ImageGridActivity图片选择页面 ---------------------------------------- 包名:com.lqr.imagepicker.ui.ImageGridActivity 1. onCreate()初始化 - 从Intent中获取showCamera参数(true) - 创建ImageGridAdapter,传入showCamera参数 - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/ui/ImageGridActivity.java 2. ImageGridAdapter显示拍照按钮 - 如果showCamera为true,在GridView的第一项显示拍照按钮 - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/adapter/ImageGridAdapter.java 六、点击拍照按钮 ---------------------------------------- 包名:com.lqr.imagepicker.ui.ImageGridActivity 1. takePhoto()方法被调用 - 检查相机权限(Manifest.permission.CAMERA) - 如果权限已授予,调用Utils.takePhoto() - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/ui/ImageGridActivity.java (165-176行) 2. Utils.takePhoto()启动系统相机 - 生成拍照输出路径:Utils.genTakePhotoOutputPath() - 创建Intent:MediaStore.ACTION_IMAGE_CAPTURE - 使用FileProvider设置输出路径 - 启动相机Activity:startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE) - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/Utils.java (77-82行) 七、拍照完成处理 ---------------------------------------- 包名:com.lqr.imagepicker.ui.ImageGridActivity 1. onActivityResult()接收拍照结果 - requestCode == ImagePicker.REQUEST_CODE_TAKE - resultCode == Activity.RESULT_OK - 调用onTakePhoto()方法 - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/ui/ImageGridActivity.java (283-299行) 2. onTakePhoto()处理拍照结果 - 发送广播通知媒体库扫描新图片:Utils.notifyToScanMedia() - 创建ImageItem对象,设置path为拍照输出路径 - 清空已选图片,将新拍的图片添加到选中列表 - 创建返回Intent,包含选中的图片列表 - 设置结果并finish():setResult(Activity.RESULT_OK, intent) - 文件位置:imagepicker/src/main/java/com/lqr/imagepicker/ui/ImageGridActivity.java (315-327行) 八、返回ImageExt处理结果 ---------------------------------------- 包名:cn.wildfire.chat.kit.conversation.ext.ImageExt 1. onActivityResult()接收结果 - requestCode == 100 - resultCode == Activity.RESULT_OK - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/ImageExt.java (68-112行) 2. 处理图片数据 - 获取选中的图片列表:data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS) - 获取是否压缩标志:data.getBooleanExtra(ImagePicker.EXTRA_COMPRESS, true) - 在后台线程处理图片(ChatManager.Instance().getWorkHandler().post()) 3. 图片处理逻辑 - 遍历选中的图片列表 - 检查是否为GIF文件(isGifFile()) - 如果是GIF,调用sendStickerMsg()发送表情 - 如果不是GIF: a. 如果需要压缩,调用ImageUtils.compressImage()压缩图片 b. 生成缩略图:ImageUtils.genThumbImgFile() c. 在主线程调用sendImgMsg()发送图片 九、发送图片消息 ---------------------------------------- 包名:cn.wildfire.chat.kit.viewmodel.MessageViewModel 1. sendImgMsg()方法 - 方法签名:sendImgMsg(Conversation conversation, List toUsers, File imageFileThumb, File imageFileSource) - 参数说明: * conversation: 会话对象 * toUsers: 目标用户列表(可为null) * imageFileThumb: 缩略图文件 * imageFileSource: 原图文件 - 文件位置:uikit/src/main/java/cn/wildfire/chat/kit/viewmodel/MessageViewModel.java 2. 发送流程 - 将File转换为Uri - 创建ImageMessageContent消息内容 - 调用ChatManager发送消息 关键代码文件清单 ======================================== 1. ConversationActivity.java uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationActivity.java 2. ConversationFragment.java uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationFragment.java 3. ConversationInputPanel.java uikit/src/main/java/cn/wildfire/chat/kit/conversation/ConversationInputPanel.java 4. ConversationExtension.java uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/core/ConversationExtension.java 5. ImageExt.java uikit/src/main/java/cn/wildfire/chat/kit/conversation/ext/ImageExt.java 6. ImageGridActivity.java imagepicker/src/main/java/com/lqr/imagepicker/ui/ImageGridActivity.java 7. ImagePicker.java imagepicker/src/main/java/com/lqr/imagepicker/ImagePicker.java 8. Utils.java imagepicker/src/main/java/com/lqr/imagepicker/Utils.java 9. MessageViewModel.java uikit/src/main/java/cn/wildfire/chat/kit/viewmodel/MessageViewModel.java 流程总结 ======================================== 用户操作流程: 1. 在ConversationActivity页面点击右下角加号按钮 2. 扩展菜单弹出,点击"照片"选项(ImageExt) 3. 打开ImageGridActivity图片选择页面 4. 点击拍照按钮(如果showCamera为true) 5. 系统相机启动,用户拍照 6. 拍照完成后,返回ImageGridActivity 7. ImageGridActivity处理拍照结果,返回ImageExt 8. ImageExt处理图片(压缩、生成缩略图) 9. 调用MessageViewModel.sendImgMsg()发送图片消息 技术要点: - 使用扩展机制(ConversationExt)实现功能模块化 - 使用ImagePicker库处理图片选择 - 使用系统相机API(MediaStore.ACTION_IMAGE_CAPTURE)拍照 - 使用FileProvider处理文件URI - 在后台线程处理图片压缩和缩略图生成 - 在主线程发送消息