インスタントメッセージングApp|画像メッセージ送信の実装

71156 ワード

インスタントメッセージングApp-画像メッセージの送信の実現
先行知識:
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;
        }
    }
}