Android聊天软件开发(基于网易云IM即时通讯)——发送图片消息(五)
16lz
2021-01-25
最近工作太忙,都没有时间写博客了。废话不多说,直接上代码。
在activity_send_message.xml添加发送图片的按钮
<?xml version="1.0" encoding="utf-8"?>
在SendMessageActivity添加按钮的注册以及点击事件
package heath.com.chat.message;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.IBinder;import android.provider.MediaStore;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import com.netease.nimlib.sdk.NIMClient;import com.netease.nimlib.sdk.RequestCallback;import com.netease.nimlib.sdk.msg.MessageBuilder;import com.netease.nimlib.sdk.msg.MsgService;import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;import com.netease.nimlib.sdk.msg.model.IMMessage;import java.io.File;import java.net.URI;import java.util.HashMap;import heath.com.chat.R;import heath.com.chat.service.IMService;import heath.com.chat.utils.Common;import heath.com.chat.utils.RealPathFromUriUtils;import heath.com.chat.utils.ToastUtil;public class SendMessageActivity extends AppCompatActivity implements View.OnClickListener { private static IMService mImService; private LinearLayout mLlReturn; private EditText mEdSendText; //调用系统相册-选择图片 private static final int IMAGE = 1; /** * 发消息 */ private Button mBtnSendText; private static TextView mTvReceiveMessage; private Button mBtnAlbum; private static ImageView mIvReceiveMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send_message); initView(); init(); } private void init() { // 绑定服务 Intent service = new Intent(SendMessageActivity.this, IMService.class); bindService(service, mMyServiceConnection, BIND_AUTO_CREATE); } @Override public void onDestroy() { super.onDestroy(); // 解绑服务 if (mMyServiceConnection != null) { unbindService(mMyServiceConnection); } } MyServiceConnection mMyServiceConnection = new MyServiceConnection(); private void initView() { mLlReturn = (LinearLayout) findViewById(R.id.ll_return); mEdSendText = (EditText) findViewById(R.id.ed_send_text); mBtnSendText = (Button) findViewById(R.id.btn_send_text); mBtnSendText.setOnClickListener(this); mTvReceiveMessage = (TextView) findViewById(R.id.tv_receive_message); mBtnAlbum = (Button) findViewById(R.id.btn_album); mIvReceiveMessage = (ImageView) findViewById(R.id.iv_receive_message); mBtnAlbum.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { default: break; case R.id.ll_return: finish(); break; case R.id.btn_album: Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); startActivityForResult(intent, IMAGE); break; case R.id.btn_send_text: final String content = mEdSendText.getText().toString();//消息文本 String account = "1";//目前这里是写死的账号 SessionTypeEnum type = SessionTypeEnum.P2P;//会话类型 final IMMessage textMessage = MessageBuilder.createTextMessage(account, type, content); NIMClient.getService(MsgService.class).sendMessage(textMessage, false).setCallback(new RequestCallback() { @Override public void onSuccess(Void param) { ToastUtil.toastOnUiThread(SendMessageActivity.this, "发送成功"); } @Override public void onFailed(int code) { Log.e("文本发送失败", "onEvent: " + code); } @Override public void onException(Throwable exception) { Log.e("文本发送异常", "onEvent: " + exception); } }); mEdSendText.setText(""); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //获取图片路径 if (requestCode == IMAGE && resultCode == Activity.RESULT_OK && data != null) { Uri selectedImage = data.getData(); //将uri转换为路径 String path = RealPathFromUriUtils.getRealPathFromUri(this, selectedImage); File file = new File(path); String account = "1";//目前这里是写死的账号 IMMessage message = MessageBuilder.createImageMessage(account, SessionTypeEnum.P2P, file, file.getName()); NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback() { @Override public void onSuccess(Void param) { try { ToastUtil.toastOnUiThread(SendMessageActivity.this, "发送成功"); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailed(int code) { Log.e("图片发送失败", "onEvent: " + code); } @Override public void onException(Throwable exception) { exception.printStackTrace(); Log.e("图片发送异常", "onEvent: " + exception); } }); } } //收到文本消息更新界面 public static void updateData(String message) { mTvReceiveMessage.setText(message); } //收到图片消息更新界面 public static void updateData1(String message) { mIvReceiveMessage.setImageURI(Uri.parse(message)); } class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out .println("--------------onServiceConnected--------------"); IMService.MyBinder binder = (IMService.MyBinder) service; mImService = binder.getService(); } @Override public void onServiceDisconnected(ComponentName name) { System.out .println("--------------onServiceDisconnected--------------"); } }}
RealPathFromUriUtils这个是将URI转换为路径的文件
package heath.com.chat.utils;import android.annotation.SuppressLint;import android.content.ContentUris;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Build;import android.provider.DocumentsContract;import android.provider.MediaStore;public class RealPathFromUriUtils { /** * 根据Uri获取图片的绝对路径 * * @param context 上下文对象 * @param uri 图片的Uri * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null */ public static String getRealPathFromUri(Context context, Uri uri) { int sdkVersion = Build.VERSION.SDK_INT; if (sdkVersion >= 19) { // api >= 19 return getRealPathFromUriAboveApi19(context, uri); } else { // api < 19 return getRealPathFromUriBelowAPI19(context, uri); } } /** * 适配api19以下(不包括api19),根据uri获取图片的绝对路径 * * @param context 上下文对象 * @param uri 图片的Uri * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null */ private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) { return getDataColumn(context, uri, null, null); } /** * 适配api19及以上,根据uri获取图片的绝对路径 * * @param context 上下文对象 * @param uri 图片的Uri * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null */ @SuppressLint("NewApi") private static String getRealPathFromUriAboveApi19(Context context, Uri uri) { String filePath = null; if (DocumentsContract.isDocumentUri(context, uri)) { // 如果是document类型的 uri, 则通过document id来进行处理 String documentId = DocumentsContract.getDocumentId(uri); if (isMediaDocument(uri)) { // MediaProvider // 使用':'分割 String id = documentId.split(":")[1]; String selection = MediaStore.Images.Media._ID + "=?"; String[] selectionArgs = {id}; filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs); } else if (isDownloadsDocument(uri)) { // DownloadsProvider Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId)); filePath = getDataColumn(context, contentUri, null, null); } } else if ("content".equalsIgnoreCase(uri.getScheme())) { // 如果是 content 类型的 Uri filePath = getDataColumn(context, uri, null, null); } else if ("file".equals(uri.getScheme())) { // 如果是 file 类型的 Uri,直接获取图片对应的路径 filePath = uri.getPath(); } return filePath; } /** * 获取数据库表中的 _data 列,即返回Uri对应的文件路径 * * @return */ private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { String path = null; String[] projection = new String[]{MediaStore.Images.Media.DATA}; Cursor cursor = null; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndexOrThrow(projection[0]); path = cursor.getString(columnIndex); } } catch (Exception e) { if (cursor != null) { cursor.close(); } } return path; } /** * @param uri the Uri to check * @return Whether the Uri authority is MediaProvider */ private static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } /** * @param uri the Uri to check * @return Whether the Uri authority is DownloadsProvider */ private static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); }}
在IMService添加接收图片的消息处理
private Observer statusObserver = new Observer() { @Override public void onEvent(IMMessage message) { if (message.getDirect() == MsgDirectionEnum.In) { if (message.getAttachStatus() == AttachStatusEnum.transferred) { if (message.getMsgType() == MsgTypeEnum.image) { //这里是图片下载成功 SendMessageActivity.updateData1(((ImageAttachment) message.getAttachment()).getThumbPath()); } } } } };
在IMService注册statusObserver和注销
在TabHostActivity增加加载动态权限
private void open() { if (Build.VERSION.SDK_INT >= 23) { int REQUEST_CODE_CONTACT = 101; String[] permissions = {android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}; //验证是否许可权限 for (String str : permissions) { if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) { //申请权限 this.requestPermissions(permissions, REQUEST_CODE_CONTACT); } } } }
项目下载地址:https://download.csdn.net/download/qq_32090185/11122479
更多相关文章
- Android图片代码换色,背景换色
- Android开发FAQ之二
- android添加以太网ethernet方法 android框架添加
- android studio将一个项目作为module(library)导入到另一个项目
- android微信朋友圈分享
- Linux常用基本命令&Android系统编译命令
- 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveI
- android 将图片内容解析成字节数组,将字节数组转换为ImageView可
- android 自动生成html报表图片