[关闭]
@weidong 2017-07-13T08:29:35.000000Z 字数 6979 阅读 387

实时通信

Android课程


实时通信使用的是第三方平台leancloud
初始化配置:https://leancloud.cn/docs/sdk_setup-android.html
实时通信开发指南:https://leancloud.cn/docs/realtime_guide-android.html

leancloud 虽然给我们提供了很方便的即时通讯sdk,但是我们还需要根据自己有用的逻辑来实现功能

初始化配置

在项目根目录下的build.gradle添加如下配置:

  1. buildscript {
  2. repositories {
  3. jcenter()
  4. //这里是 LeanCloud 的包仓库
  5. maven {
  6. url "http://mvn.leancloud.cn/nexus/content/repositories/public"
  7. }
  8. }
  9. }
  10. allprojects {
  11. repositories {
  12. jcenter()
  13. //这里是 LeanCloud 的包仓库
  14. maven {
  15. url "http://mvn.leancloud.cn/nexus/content/repositories/public"
  16. }
  17. }
  18. }

在项目app目录下的build.gradle添加如下配置:

  1. //avoscloud-push 为推送与实时聊天需要的包
  2. compile ('cn.leancloud.android:avoscloud-push:v4.0@aar'){transitive = true}

了解Gradle,可以查看此链接

初始化SDK

配置Application类

  1. //类名随意定义
  2. public class MyApplication extends Application {
  3. @Override
  4. public void onCreate() {
  5. super.onCreate();
  6. // 初始化参数依次为 this, AppId, AppKey
  7. AVOSCloud.initialize(this,"EkMW81DInN4eoh61yJSuMSIQ-gzGzoHsz","80FiCJK6omszBpfxjjFAmCqo");
  8. AVOSCloud.setDebugLogEnabled(true);
  9. }
  10. }
  1. <!-- 基础模块(必须加入以下声明)START -->
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.INTERNET"/>
  4. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  5. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  6. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  7. <!-- 基础模块 END -->
  8. <application
  9. android:name="刚刚定义的类的全类名">
  10. <!-- 实时通信模块、推送(均需要加入以下声明) START -->
  11. <!-- 实时通信模块、推送都要使用 PushService -->
  12. <service android:name="com.avos.avoscloud.PushService"/>
  13. <receiver android:name="com.avos.avoscloud.AVBroadcastReceiver">
  14. <intent-filter>
  15. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  16. <action android:name="android.intent.action.USER_PRESENT"/>
  17. <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  18. </intent-filter>
  19. </receiver>
  20. <!-- 实时通信模块、推送 END -->
  21. </application>

验证是否配置成功

  1. public void test() {
  2. // 测试 SDK 是否正常工作的代码
  3. AVObject testObject = new AVObject("TestObject");
  4. testObject.put("name", "杨伟东");
  5. testObject.saveInBackground(new SaveCallback() {
  6. @Override
  7. public void done(AVException e) {
  8. if (e == null) {
  9. Log.d(TAG, "保存成功啦!");
  10. }
  11. }
  12. });
  13. }

实时通信(发送消息)

初始化通信服务(登陆)

  1. /**
  2. * AVIMClient.open(AVIMClientCallback cb) 这个方法表示开始连接
  3. * 云端服务器(即启动实时通信服务),它在整个使用周期内只需要调用一次
  4. * 这里演示使用当前登录的用户ID 为 clientId
  5. */
  6. public void login() {
  7. //登陆,以当前登录的用户id为客户端id进行登录
  8. LoginResponse loginInfo = AppConfigUtils.getInstance().getLoginInfo(app);
  9. if (loginInfo != null && !TextUtils.isEmpty(loginInfo.getObjectId())) {
  10. AVIMClient user = AVIMClient.getInstance(AppConfigUtils.getInstance().getLoginInfo(app).getObjectId());
  11. user.open(new AVIMClientCallback() {
  12. @Override
  13. public void done(AVIMClient avimClient, AVIMException e) {
  14. Log.e(TAG, "done: 登陆成功");
  15. }
  16. });
  17. }
  18. }

发送消息

  1. //创建对话,以及发送消息
  2. public void sendMessageToJerryFromTom() {
  3. // 用当前登陆的用户ID作为clientId,获取AVIMClient对象实例
  4. AVIMClient tom = AVIMClient.getInstance("bbb");
  5. // 与服务器连接
  6. tom.open(new AVIMClientCallback() {
  7. @Override
  8. public void done(AVIMClient client, AVIMException e) {
  9. if (e == null) {
  10. // 创建与Jerry之间的对话
  11. client.createConversation(Arrays.asList("Jerry"), "Tom & Jerry", null,
  12. new AVIMConversationCreatedCallback() {
  13. @Override
  14. public void done(AVIMConversation conversation, AVIMException e) {
  15. if (e == null) {
  16. AVIMTextMessage msg = new AVIMTextMessage();
  17. msg.setText("Android 好流弊。。。。");
  18. // 发送消息
  19. conversation.sendMessage(msg, new AVIMConversationCallback() {
  20. @Override
  21. public void done(AVIMException e) {
  22. if (e == null) {
  23. Log.d(TAG, "发送成功!");
  24. }
  25. }
  26. });
  27. }
  28. }
  29. });
  30. }
  31. }
  32. });
  33. }

接收消息

在 Android SDK 中注册接收消息的监听有两个不同的方法:
registerDefaultMessageHandlerregisterMessageHandler

当客户端收到一条消息的时候,会优先执行registerMessageHandler() 方法注册的监听,
通过registerMessageHandler注册的监听是可以同存的。

当发现当前没有通过registerMessageHandler方法注册的监听,则会去通知 registerDefaultMessageHandler 方法注册的监听。

通过在 UI 组件(比如 Activity)的 onResume 方法中间去调用 registerMessageHandler,而在 onPaused 方法中间调用 unregisterMessageHandler 的组合,让对应的 messageHandler 处理当前页面的处理逻辑;而当没有页面时,则通过 defaultMessageHandler 去发送 Notification

消息分类

//注册默认消息

  1. AVIMMessageManager.registerDefaultMessageHandler(new AVIMMessageHandler() {
  2. @Override
  3. public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client) {
  4. super.onMessage(message, conversation, client);
  5. Log.e(TAG, "onMessage: 接收到消息啦");
  6. }
  7. });

//普通消息,区分消息种类

  1. AVIMTypedMessageHandler avimMessageHandler = new AVIMTypedMessageHandler<AVIMTypedMessage> (){
  2. @Override
  3. public void onMessage(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {
  4. // 请按自己需求改写
  5. switch(message.getMessageType()) {
  6. case -1:
  7. AVIMTextMessage textMsg = (AVIMTextMessage)message;
  8. Log.d(TAG,"收到文本消息:" + textMsg.getText() + ", msgId:" + textMsg.getMessageId());
  9. LCIMIMTypeMessageEvent event = new LCIMIMTypeMessageEvent();
  10. event.message = textMsg;
  11. event.conversation = conversation;
  12. onEvent(event);
  13. break;
  14. case -2:
  15. AVIMFileMessage fileMsg = (AVIMFileMessage)message;
  16. Log.d(TAG,"收到文件消息。msgId=" + fileMsg.getMessageId() + ", url=" + fileMsg.getFileUrl() + ", size=" + fileMsg.getSize());
  17. break;
  18. case -3:
  19. AVIMImageMessage imageMsg = (AVIMImageMessage)message;
  20. Log.d(TAG,"收到图片消息。msgId=" + imageMsg.getMessageId() + ", url=" + imageMsg.getFileUrl() + ", width=" + imageMsg.getWidth() + ", height=" + imageMsg.getHeight());
  21. break;
  22. case -4:
  23. AVIMAudioMessage audioMsg = (AVIMAudioMessage)message;
  24. Log.d(TAG,"收到音频消息。msgId=" + audioMsg.getMessageId() + ", url=" + audioMsg.getFileUrl() + ", duration=" + audioMsg.getDuration());
  25. break;
  26. case -5:
  27. AVIMVideoMessage videoMsg = (AVIMVideoMessage) message;
  28. Log.d(TAG,"收到视频消息。msgId=" + videoMsg.getMessageId() + ", url=" + videoMsg.getFileUrl() + ", duration=" + videoMsg.getDuration());
  29. break;
  30. case -6:
  31. AVIMLocationMessage locMsg = (AVIMLocationMessage)message;
  32. Log.d(TAG,"收到位置消息。msgId=" + locMsg.getMessageId() + ", latitude=" + locMsg.getLocation().getLatitude() + ", longitude=" + locMsg.getLocation().getLongitude());
  33. break;
  34. }
  35. }
  36. };

获取会话记录

  1. /**
  2. * 获取最近会话列表
  3. */
  4. public void getConversations(){
  5. String objectId = AppConfigUtils.getInstance().getLoginInfo(getActivity()).getObjectId();
  6. AVIMClient client = AVIMClient.getInstance(objectId);
  7. AVIMConversationsQuery query = client.getConversationsQuery();
  8. query.setWithLastMessagesRefreshed(true);
  9. query.findInBackground(new AVIMConversationQueryCallback(){
  10. @Override
  11. public void done(List<AVIMConversation> convs, AVIMException e){
  12. if(e==null){
  13. //convs就是获取到的conversation列表
  14. //注意:按每个对话的最后更新日期(收到最后一条消息的时间)倒序排列
  15. Log.e(TAG, "done: 会话大小" +convs.size());
  16. }
  17. }
  18. });
  19. }

会话属性

image.png-109.2kB

结束通信服务(退出)

  1. /**
  2. * 用户退出实时通信服务(断开 LeanCloud 云端服务器连接)时需要在 IMClient
  3. * 对象上调用 AVIMClient.close(AVIMClientCallback cb)。
  4. */
  5. public void close(){
  6. //关闭通信服务
  7. LoginResponse loginInfo = AppConfigUtils.getInstance().getLoginInfo(app);
  8. if (loginInfo != null && !TextUtils.isEmpty(loginInfo.getObjectId())) {
  9. AVIMClient user = AVIMClient.getInstance(AppConfigUtils.getInstance().getLoginInfo(app).getObjectId());
  10. user.close(new AVIMClientCallback() {
  11. @Override
  12. public void done(AVIMClient avimClient, AVIMException e) {
  13. Log.e(TAG, "done: 退出成功");
  14. }
  15. });
  16. }
  17. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注