インスタントメッセージングApp|画像メッセージ送信の実装
71156 ワード
インスタントメッセージングApp-画像メッセージの送信の実現
先行知識:
1、onActivity Result()の使い方
Activity Aが2つある場合、B.AのインタフェースからBのインタフェースにジャンプして、対応する操作を実行する必要があります.操作が完了すると、BのインタフェースからAのインタフェースにジャンプし、A処理に渡すデータも返されるかもしれません.このようなデータ交流はコールバック関数onActivity Result()で実現できます.
ビジネスプロセス
1、カメラ/アルバム画像を読み取る
2、画像メッセージの送信
3、photoviewプレビュー
1、カメラ実現コードを読み取る
2、アルバム実現コードにジャンプ
以上の2つのメソッドはFileHelperファイルのヘルプクラスにカプセル化されています.
そしてチャットActivityでFileHelperコールバックのピクチャデータを処理する
送信ピクチャ呼び出し融雲SDK、以下にcallbackがありますが、送信ピクチャの進捗、成功するかどうかなどのコールバックを省略してサービスに直接書けばいいのです.具体的なコールバック処理が必要な場合は、コールバックを参照リストに配置すればよい.
adapterマルチデータバインド
クエリー・サーバーのメッセージqueryMessage()は、アクセスするたびに呼び出され、履歴を解析してレンダリングされます.
サービスの論理:
イベントをActivityでonMessageEventで処理するには、次の手順に従います.
画像のプレビューを以下に示します.
オープンソースコントロールの使用
先行知識:
1、onActivity Result()の使い方
Activity Aが2つある場合、B.AのインタフェースからBのインタフェースにジャンプして、対応する操作を実行する必要があります.操作が完了すると、BのインタフェースからAのインタフェースにジャンプし、A処理に渡すデータも返されるかもしれません.このようなデータ交流はコールバック関数onActivity Result()で実現できます.
ビジネスプロセス
1、カメラ/アルバム画像を読み取る
2、画像メッセージの送信
3、photoviewプレビュー
1、カメラ実現コードを読み取る
/**
*
* , ,
*
* @param mActivity
*/
public void toCamera(Activity mActivity) {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String fileName = simpleDateFormat.format(new Date());
tempFile = new File(Environment.getExternalStorageDirectory(), fileName + ".jpg");
// Android N
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
imageUri = Uri.fromFile(tempFile);
} else {
// FileProvider
imageUri = FileProvider.getUriForFile(mActivity,
mActivity.getPackageName() + ".fileprovider", tempFile);
//
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
mActivity.startActivityForResult(intent, CAMEAR_REQUEST_CODE);
} catch (Exception e) {
Toast.makeText(mActivity, " ", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
2、アルバム実現コードにジャンプ
/**
*
*
* @param mActivity
*/
public void toAlbum(Activity mActivity) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
mActivity.startActivityForResult(intent, ALBUM_REQUEST_CODE);
}
以上の2つのメソッドはFileHelperファイルのヘルプクラスにカプセル化されています.
そしてチャットActivityでFileHelperコールバックのピクチャデータを処理する
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == FileHelper.CAMEAR_REQUEST_CODE) {
uploadFile = FileHelper.getInstance().getTempFile();
} else if (requestCode == FileHelper.ALBUM_REQUEST_CODE) {
Uri uri = data.getData();
if (uri != null) {
//String path = uri.getPath();
//
String path = FileHelper.getInstance().getRealPathFromURI(this, uri);
//LogUtils.e("path:" + path);
if (!TextUtils.isEmpty(path)) {
uploadFile = new File(path);
}
}
}
if (uploadFile != null) {
//
CloudManager.getInstance().sendImageMessage(yourUserId, uploadFile);
//
addImage(1, uploadFile);
uploadFile = null;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
送信ピクチャ呼び出し融雲SDK、以下にcallbackがありますが、送信ピクチャの進捗、成功するかどうかなどのコールバックを省略してサービスに直接書けばいいのです.具体的なコールバック処理が必要な場合は、コールバックを参照リストに配置すればよい.
private RongIMClient.SendImageMessageCallback sendImageMessageCallback = new RongIMClient.SendImageMessageCallback() {
@Override
public void onAttached(Message message) {
LogUtils.i("onAttached");
}
@Override
public void onError(Message message, RongIMClient.ErrorCode errorCode) {
LogUtils.i("onError:" + errorCode);
}
@Override
public void onSuccess(Message message) {
LogUtils.i("onSuccess");
}
@Override
public void onProgress(Message message, int i) {
LogUtils.i("onProgress:" + i);
}
};
/**
*
*
* @param targetId ID
* @param file
*/
public void sendImageMessage(String targetId, File file) {
ImageMessage imageMessage = ImageMessage.obtain(Uri.fromFile(file), Uri.fromFile(file), true);
RongIMClient.getInstance().sendImageMessage(
Conversation.ConversationType.PRIVATE,
targetId,
imageMessage,
null,
null,
sendImageMessageCallback);
}
adapterマルチデータバインド
mChatAdapter = new CommonAdapter<>(mList, new CommonAdapter.OnMoreBindDataListener<ChatModel>() {
@Override
public int getItemType(int position) {
return mList.get(position).getType();
}
@Override
public void onBindViewHolder(final ChatModel model, CommonViewHolder viewHolder, int type, int position) {
// , , chatModel type
switch (model.getType()) {
case TYPE_LEFT_IMAGE:
viewHolder.setImageUrl(ChatActivity.this, R.id.iv_left_img, model.getImgUrl());
viewHolder.setImageUrl(ChatActivity.this, R.id.iv_left_photo, yourUserPhoto);
viewHolder.getView(R.id.iv_left_img).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImagePreviewActivity.startActivity(
ChatActivity.this, true, model.getImgUrl());
}
});
break;
case TYPE_RIGHT_IMAGE://
if (TextUtils.isEmpty(model.getImgUrl())) {
if (model.getLocalFile() != null) {
//
viewHolder.setImageFile(ChatActivity.this, R.id.iv_right_img, model.getLocalFile());
viewHolder.getView(R.id.iv_right_img).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImagePreviewActivity.startActivity(
ChatActivity.this, false, model.getLocalFile().getPath());
}
});
}
} else {
viewHolder.setImageUrl(ChatActivity.this, R.id.iv_right_img, model.getImgUrl());
viewHolder.setImageUrl(ChatActivity.this, R.id.iv_right_photo, meUserPhoto);
viewHolder.getView(R.id.iv_right_img).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImagePreviewActivity.startActivity(
ChatActivity.this, true, model.getImgUrl());
}
});
}
break;
}
}
// , chatModel type
@Override
public int getLayoutId(int type) {
} else if (type == TYPE_LEFT_IMAGE) {
return R.layout.layout_chat_left_img;
} else if (type == TYPE_RIGHT_IMAGE) {
return R.layout.layout_chat_right_img;
}
return 0;
}
});
mChatView.setAdapter(mChatAdapter);
/**
*
*
* @param model
*/
private void baseAddItem(ChatModel model) {
long currentTime = System.currentTimeMillis();
LogUtils.e("currentTime:" + currentTime);
if (CommonUtils.isEmpty(mList)) {
// : , , ,
ChatModel lastModel = mList.get(mList.size() - 1);
long lastTime = lastModel.getMessageTime();
LogUtils.e("lastTime:" + lastTime);
//
if (Math.abs(lastTime - currentTime) > 5 * 60 * 1000) {
addTimeItem(currentTime);
}
}
model.setMessageTime(currentTime);
mList.add(model);
mChatAdapter.notifyDataSetChanged();
//
mChatView.scrollToPosition(mList.size() - 1);
}
/**
*
*
* @param index
* @param url
*/
private void addImage(int index, String url) {
ChatModel model = new ChatModel();
if (index == 0) {
model.setType(TYPE_LEFT_IMAGE);
} else {
model.setType(TYPE_RIGHT_IMAGE);
}
model.setImgUrl(url);
baseAddItem(model);
}
/**
*
*
* @param index
* @param file
*/
private void addImage(int index, File file) {
ChatModel model = new ChatModel();
if (index == 0) {
model.setType(TYPE_LEFT_IMAGE);
} else {
model.setType(TYPE_RIGHT_IMAGE);
}
model.setLocalFile(file);
baseAddItem(model);
}
クエリー・サーバーのメッセージqueryMessage()は、アクセスするたびに呼び出され、履歴を解析してレンダリングされます.
/**
*
*
* @param messages
*/
private void parsingListMessage(List<Message> messages) {
//
Collections.reverse(messages);
//
for (int i = 0; i < messages.size(); i++) {
Message m = messages.get(i);
String objectName = m.getObjectName();
if (objectName.equals(CloudManager.MSG_IMAGE_NAME)) {
ImageMessage imageMessage = (ImageMessage) m.getContent();
String url = imageMessage.getRemoteUri().toString();
if (!TextUtils.isEmpty(url)) {
LogUtils.i("url:" + url);
if (m.getSenderUserId().equals(yourUserId)) {
addImage(0, url);//
} else {
addImage(1, url);//
}
}
}
}
}
}
サービスの論理:
//
CloudManager.getInstance().setOnReceiveMessageListener((message, i) -> {
parsingImMessage(message);
return false;
});
/**
*
*
* @param message
*/
private void parsingImMessage(Message message) {
LogUtils.i("message:" + message);
String objectName = message.getObjectName();
if (objectName.equals(CloudManager.MSG_IMAGE_NAME)) {
try {
ImageMessage imageMessage = (ImageMessage) message.getContent();
String url = imageMessage.getRemoteUri().toString();
if (!TextUtils.isEmpty(url)) {
LogUtils.i("url:" + url);
MessageEvent event = new MessageEvent(EventManager.FLAG_SEND_IMAGE);
event.setImgUrl(url);
event.setUserId(message.getSenderUserId());
EventManager.post(event);
pushSystem(message.getSenderUserId(), 1, 0, 0, getString(R.string.text_chat_record_img));
}
} catch (Exception e) {
LogUtils.e("e." + e.toString());
e.printStackTrace();
}
}
イベントをActivityでonMessageEventで処理するには、次の手順に従います.
case EventManager.FLAG_SEND_IMAGE:
addImage(0, event.getImgUrl());//
break;
画像のプレビューを以下に示します.
オープンソースコントロールの使用
**
* FileName: ImagePreviewActivity
* Profile:
*/
public class ImagePreviewActivity extends BaseUIActivity implements View.OnClickListener {
/**
*
* @param mContext
* @param isUrl
* @param url
*/
public static void startActivity(Context mContext, boolean isUrl, String url) {
Intent intent = new Intent(mContext, ImagePreviewActivity.class);
intent.putExtra(Constants.INTENT_IMAGE_TYPE, isUrl);
intent.putExtra(Constants.INTENT_IMAGE_URL, url);
mContext.startActivity(intent);
}
private PhotoView photo_view;
private ImageView iv_back;
private TextView tv_download;
//
private String url;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_preview);
initView();
}
private void initView() {
photo_view = (PhotoView) findViewById(R.id.photo_view);
iv_back = (ImageView) findViewById(R.id.iv_back);
tv_download = (TextView)findViewById(R.id.tv_download);
iv_back.setOnClickListener(this);
tv_download.setOnClickListener(this);
Intent intent = getIntent();
boolean isUrl = intent.getBooleanExtra(Constants.INTENT_IMAGE_TYPE,false);
url = intent.getStringExtra(Constants.INTENT_IMAGE_URL);
// ,File
tv_download.setVisibility(isUrl?View.VISIBLE:View.GONE);
if(isUrl){
GlideHelper.loadUrl(this,url,photo_view);
}else{
GlideHelper.loadFile(this,new File(url),photo_view);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_back:
finish();
break;
case R.id.tv_download:
Toast.makeText(this, getString(R.string.text_iv_pre_downloading), Toast.LENGTH_SHORT).show();
GlideHelper.loadUrlToBitmap(this, url, new GlideHelper.OnGlideBitmapResultListener() {
@Override
public void onResourceReady(Bitmap resource) {
if(resource != null){
FileHelper.getInstance().saveBitmapToAlbum(ImagePreviewActivity.this,resource);
}else{
Toast.makeText(ImagePreviewActivity.this, getString(R.string.text_iv_pre_save_fail), Toast.LENGTH_SHORT).show();
}
}
});
break;
}
}
}