Android SDK 语音及图片消息详解

    本文档将详细介绍融云的语音及图片消息接口功能及使用说明。阅读本文前,我们假设您已经阅读了融云 Android 开发指南,并掌握融云 SDK 的基本用法。

    语音消息

    用来发送语音片段消息,您可以通过融云客户端 IMLib 接口或 Server API 接口发送语音消息。如果您使用的是融云 IMKit 则该功能已经在 SDK 中封装好,直接使用即可。以下为通过融云 IMLib 及 Server API 发送语音消息的方法。

    从客户端发送消息

    获取要发送的语音文件格式为 AMR,并获行语音时长,通过 sendMessage 方法,传入相应的参数即可发送语音消息,方法说明参见 API 文档链接

    消息类名:VoiceMessage

    代码示例:

    File voiceFile = new File(getCacheDir(), "voice.amr");
    
    try {
        // 读取音频文件。
        InputStream is = getAssets().open("BlackBerry.amr");
    
        OutputStream os = new FileOutputStream(voiceFile);
    
        byte[] buffer = new byte[1024];
    
        int bytesRead;
    
        // 写入缓存文件。
        while((bytesRead = is.read(buffer)) !=-1){
            os.write(buffer, 0, bytesRead);
        }
    
        is.close();
        os.flush();
        os.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    /**
     * 获取语音消息实体。
     *
     * @param Uri       语音 Uri 。
     * @param duration  语音时长(单位:秒)。
     */
    VoiceMessage vocMsg = VoiceMessage.obtain(Uri.fromFile(voiceFile), 10);
    
    /**
     * 发送消息。
     *
     * @param type        会话类型。
     * @param targetId    目标 Id。根据不同的 conversationType,可能是用户 Id、讨论组 Id、群组 Id 或聊天室 Id。
     * @param content     消息内容。
     * @param pushContent push 时提示内容。
     * @param callback    发送消息的回调。
     * @return 发送的消息实体。
     */
    RongIM.getInstance().getRongIMClient().sendMessage(Conversation.ConversationType.PRIVATE, "9517", vocMsg, "", new RongIMClient.SendMessageCallback() {
        @Override
        public void onError(Integer messageId, RongIMClient.ErrorCode e) {
    
        }
    
        @Override
        public void onSuccess(Integer integer) {
    
        }
    });
    
    注意:在对内容进行 Base64 编码 Encode 后,需要将所有 \r\n 替换成空,否则无法进行正确解析。建议语音消息时长最小为 1 秒,最长不能超过 60 秒。语音格式为 AMR

    从服务端发送消息

    如果您需要从服务端发送语音消息,融云也提供了 Server API 接口,下面以发送单聊消息为例,说明如何发送语音消息。

    消息 ObjectName:RC:VcMsg

    消息的结构:{"content":"bhZPzJXimRwrtvc=","duration":7,"extra":""}

    其中 content 为语音消息录制转码成 AMR 格式后,进行 Base64 编码 Encode 后的结果值,duration 为语音消息的时长(单位:秒),extra 可以放置任意的数据内容,也可以去掉此属性。

    代码示例:

    Request:

    POST /message/private/publish.json HTTP/1.1
    Host: api.cn.ronghub.com
    App-Key: uwd1c0sxdlx2
    Timestamp: 1408706337
    Nonce: 14314
    Signature: 890b422b75c1c5cb706e4f7921df1d94e69c17f4
    Content-Type: Application/x-www-form-urlencoded
    
    content={"content":"IyFBTVIKPJEXFr5meeHgAeev8","duration":3,"extra":"helloExtra"}&fromUserId=2191&toUserId=2191&toUserId=2192&objectName=RC:TxtMsg&pushContent=thisisapush&pushData={\"pushData\":\"hello\"}&count=1
    

    Response:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {"code":200}
    

    发送单聊消息方法参数说明,请参见文档

    图片消息

    用来发送图片类消息,您可以通过融云客户端 IMLib 接口或 Server API 接口发送图片消息。如果您使用的是融云 IMKit 则该功能已经在 SDK 中封装好,直接使用即可。以下为通过融云 IMLib 及 Server API 发送语音消息的方法。

    图片上传机制

    图片消息包括两个主要部分:缩略图和大图,缩略图直接 Base64 编码后放入 content 中,大图首先上传到文件服务器(融云 SDK 中默认上传到七牛云存储,图片有效期为 6 个月),然后将云存储上的大图地址放入消息体中。流程示意如下:

    App -> RongCloud IM SDK: 调用发送图片消息接口 RongCloud IM SDK -> File Server: 上传大图,到文件服务器 RongCloud IM SDK --> App: 更新图片上传进度 File Server --> RongCloud IM SDK: 上传成功,返回上传大图的地址 RongCloud IM SDK -> RongCloud IM Server: 发送图片消息(内附缩略图内容和大图地址) RongCloud IM Server --> RongCloud IM SDK: 返回发送成功状态 RongCloud IM SDK --> App: 返回发送成功状态

    如果,您在发送图片消息时,希望将图片上传到自己的服务器然后发送图片消息。流程示意如下:

    App -> RongCloud IM SDK: 调用发送图片消息接口 RongCloud IM SDK -> RongCloud IM SDK: 存储图片消息 RongCloud IM SDK --> App: 通过 App 上传图片到文件服务器 App -> App File Server: 上传大图,到自己的文件服务器 App -> RongCloud IM SDK: 更新图片上传进度 App File Server --> App: 上传成功,返回上传大图的地址 App -> RongCloud IM SDK: 通过融云发送消息,并附带图片地址 RongCloud IM SDK -> RongCloud IM Server: 发送图片消息(内附缩略图内容和大图地址) RongCloud IM Server --> RongCloud IM SDK: 返回发送成功状态 RongCloud IM SDK --> App: 返回发送成功状态

    图片缩略图机制

    缩略图尺寸为:240 x 240 像素,以宽度和高度中较长的边不超过 240 像素等比压缩。

    大图尺寸为:960 x 960 像素,以宽度和高度中较长的边不超过 960 像素等比压缩。

    从客户端发送消息

    调用 sendMessage 方法,传入相应的参数即可发送图片消息。方法说明参见 API 文档链接

    消息类名:ImageMessage

    代码示例:

     /**
     * 发送图片消息方法。
     */
    
    //选择手机端本地图片,例如:
    String localImagePath = "/sdcard/test.jpg";
    //构造图片消息对象,两个参数传同一个图片路径即可。
    ImageMessage imgMsg = ImageMessage.obtain(Uri.parse("file://" + localImagePath), Uri.parse("file://" + localImagePath));
    
     //使用 sendImageMessage 发出。
     RongIM.getInstance().getRongIMClient().sendImageMessage(Conversation.ConversationType.PRIVATE, "9527", imgMsg, null, null, new RongIMClient.SendImageMessageCallback() {
         @Override
         public void onAttached(Message message) {
            //保存数据库成功
         }
    
         @Override
         public void onError(Message message, RongIMClient.ErrorCode errorCode) {
            //发送失败
         }
    
         @Override
         public void onSuccess(Message message) {
            //发送成功
         }
    
         @Override
         public void onProgress(Message message, int i) {
            //发送进度
         }
     });
    

    如果,您在发送图片消息时,希望将图片上传到自己的服务器然后发送图片消息,代码示例如下:

    /**
     * 发送图片消息,可以使用该方法将图片上传到自己的服务器发送,同时更新图片状态。
     * 该方法适用于使用者自己上传图片,并通过 listener 将上传进度更新在UI上显示。
     *
     * @param message 发送消息的实体。
     * @param pushContent push 内容,为空时不 push 信息。
     * @param pushData push 附加信息,开发者根据自己的需要设置 pushData。
     * @param callback 发送消息的回调,该回调携带 listener 对象,使用者可以调用其方法,更新图片上传进度。
     */
     RongIM.getInstance().getRongIMClient().sendImageMessage(io.rong.imlib.model.Message.obtain("9527", Conversation.ConversationType.PRIVATE, imgmsg), null, null, new RongIMClient.SendImageMessageWithUploadListenerCallback() {
       @Override
       public void onAttached(io.rong.imlib.model.Message message, RongIMClient.uploadImageStatusListener watcher) {
          //这个upload是开发者自己将图片上传服务器的方法,需要要开发者自己实现,然后把ImageMessage和wather传进去
          upload((ImageMessage) message.getContent(),watcher);
       }
    
       @Override
       public void onError(io.rong.imlib.model.Message message, RongIMClient.ErrorCode code) {
          //发送失败的处理
       }
    
       @Override
       public void onSuccess(io.rong.imlib.model.Message message) {
          //发送成功的处理
       }
    
       @Override
       public void onProgress(io.rong.imlib.model.Message message, int progress) {
          //对上传图片进度的处理
       }
     });
    
    //在开发者上传服务器的方法示例,此方法需要开发者自己实现,在上传的过程中将状态更新给 `watcher`。
    public void upload(ImageMessage imageMessage, RongIMClient.uploadImageStatusListener watcher){
    
     //此处为您将图片上传至自己服务器的操作。
    
     //您需要在上传过程中将progress更新给watcher,这个progress是您的上传过程给出的.
     watcher.update(progress);
       if(progress==100) {
         imageMessage.setRemoteUri(uri); //这个uri是您服务器图片的url.
         watcher.success();
       }
     }
    

    sendImageMessage 方法说明,请参见 API 文档链接

    从服务端发送消息

    如果您需要从服务端发送图片消息,融云也提供了 Server API 接口,下面以发送单聊消息为例,说明如何发送图片消息。

    消息 ObjectName:RC:ImgMsg

    消息的结构:{"content":"bhZPzJXimRwrtvc=","imageUri":"http://p1.cdn.com/fds78ruhi.jpg","extra":""}

    其中 content 为图片内容进行 Base64 编码的结果值,imageUri 为图片上传到图片存储服务器后的地址,extra 可以放置任意的数据内容,也可以去掉此属性。

    代码示例:

    Request:

    POST /message/private/publish.json HTTP/1.1
    Host: api.cn.ronghub.com
    App-Key: uwd1c0sxdlx2
    Timestamp: 1408706337
    Nonce: 14314
    Signature: 890b422b75c1c5cb706e4f7921df1d94e69c17f4
    Content-Type: Application/x-www-form-urlencoded
    
    content={"content":"bhZPzJXimRwrtvc=","icon":"http://www.demo.com/p1.png","imageUri":"http://www.demo.com/1.jpg","extra":"helloExtra"}&fromUserId=2191&toUserId=2191&toUserId=2192&objectName=RC:TxtMsg&pushContent=thisisapush&pushData={\"pushData\":\"hello\"}&count=1
    

    Response:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {"code":200}
    

    发送单聊消息方法参数说明,请参见文档