@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
添加如下配置:
buildscript {
repositories {
jcenter()
//这里是 LeanCloud 的包仓库
maven {
url "http://mvn.leancloud.cn/nexus/content/repositories/public"
}
}
}
allprojects {
repositories {
jcenter()
//这里是 LeanCloud 的包仓库
maven {
url "http://mvn.leancloud.cn/nexus/content/repositories/public"
}
}
}
在项目app目录下的build.gradle
添加如下配置:
//avoscloud-push 为推送与实时聊天需要的包
compile ('cn.leancloud.android:avoscloud-push:v4.0@aar'){transitive = true}
Application和Activity,Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,且Application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。
//类名随意定义
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化参数依次为 this, AppId, AppKey
AVOSCloud.initialize(this,"EkMW81DInN4eoh61yJSuMSIQ-gzGzoHsz","80FiCJK6omszBpfxjjFAmCqo");
AVOSCloud.setDebugLogEnabled(true);
}
}
<!-- 基础模块(必须加入以下声明)START -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 基础模块 END -->
<application
android:name="刚刚定义的类的全类名">
<!-- 实时通信模块、推送(均需要加入以下声明) START -->
<!-- 实时通信模块、推送都要使用 PushService -->
<service android:name="com.avos.avoscloud.PushService"/>
<receiver android:name="com.avos.avoscloud.AVBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<!-- 实时通信模块、推送 END -->
</application>
public void test() {
// 测试 SDK 是否正常工作的代码
AVObject testObject = new AVObject("TestObject");
testObject.put("name", "杨伟东");
testObject.saveInBackground(new SaveCallback() {
@Override
public void done(AVException e) {
if (e == null) {
Log.d(TAG, "保存成功啦!");
}
}
});
}
/**
* AVIMClient.open(AVIMClientCallback cb) 这个方法表示开始连接
* 云端服务器(即启动实时通信服务),它在整个使用周期内只需要调用一次
* 这里演示使用当前登录的用户ID 为 clientId
*/
public void login() {
//登陆,以当前登录的用户id为客户端id进行登录
LoginResponse loginInfo = AppConfigUtils.getInstance().getLoginInfo(app);
if (loginInfo != null && !TextUtils.isEmpty(loginInfo.getObjectId())) {
AVIMClient user = AVIMClient.getInstance(AppConfigUtils.getInstance().getLoginInfo(app).getObjectId());
user.open(new AVIMClientCallback() {
@Override
public void done(AVIMClient avimClient, AVIMException e) {
Log.e(TAG, "done: 登陆成功");
}
});
}
}
//创建对话,以及发送消息
public void sendMessageToJerryFromTom() {
// 用当前登陆的用户ID作为clientId,获取AVIMClient对象实例
AVIMClient tom = AVIMClient.getInstance("bbb");
// 与服务器连接
tom.open(new AVIMClientCallback() {
@Override
public void done(AVIMClient client, AVIMException e) {
if (e == null) {
// 创建与Jerry之间的对话
client.createConversation(Arrays.asList("Jerry"), "Tom & Jerry", null,
new AVIMConversationCreatedCallback() {
@Override
public void done(AVIMConversation conversation, AVIMException e) {
if (e == null) {
AVIMTextMessage msg = new AVIMTextMessage();
msg.setText("Android 好流弊。。。。");
// 发送消息
conversation.sendMessage(msg, new AVIMConversationCallback() {
@Override
public void done(AVIMException e) {
if (e == null) {
Log.d(TAG, "发送成功!");
}
}
});
}
}
});
}
}
});
}
在 Android SDK 中注册接收消息的监听有两个不同的方法:
registerDefaultMessageHandler
和 registerMessageHandler
当客户端收到一条消息的时候,会优先执行registerMessageHandler()
方法注册的监听,
通过registerMessageHandler
注册的监听是可以同存的。
当发现当前没有通过registerMessageHandler
方法注册的监听,则会去通知 registerDefaultMessageHandler
方法注册的监听。
通过在 UI 组件(比如 Activity)的 onResume
方法中间去调用 registerMessageHandler
,而在 onPaused
方法中间调用 unregisterMessageHandler
的组合,让对应的 messageHandler
处理当前页面的处理逻辑;而当没有页面时,则通过 defaultMessageHandler
去发送 Notification
。
//注册默认消息
AVIMMessageManager.registerDefaultMessageHandler(new AVIMMessageHandler() {
@Override
public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client) {
super.onMessage(message, conversation, client);
Log.e(TAG, "onMessage: 接收到消息啦");
}
});
//普通消息,区分消息种类
AVIMTypedMessageHandler avimMessageHandler = new AVIMTypedMessageHandler<AVIMTypedMessage> (){
@Override
public void onMessage(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {
// 请按自己需求改写
switch(message.getMessageType()) {
case -1:
AVIMTextMessage textMsg = (AVIMTextMessage)message;
Log.d(TAG,"收到文本消息:" + textMsg.getText() + ", msgId:" + textMsg.getMessageId());
LCIMIMTypeMessageEvent event = new LCIMIMTypeMessageEvent();
event.message = textMsg;
event.conversation = conversation;
onEvent(event);
break;
case -2:
AVIMFileMessage fileMsg = (AVIMFileMessage)message;
Log.d(TAG,"收到文件消息。msgId=" + fileMsg.getMessageId() + ", url=" + fileMsg.getFileUrl() + ", size=" + fileMsg.getSize());
break;
case -3:
AVIMImageMessage imageMsg = (AVIMImageMessage)message;
Log.d(TAG,"收到图片消息。msgId=" + imageMsg.getMessageId() + ", url=" + imageMsg.getFileUrl() + ", width=" + imageMsg.getWidth() + ", height=" + imageMsg.getHeight());
break;
case -4:
AVIMAudioMessage audioMsg = (AVIMAudioMessage)message;
Log.d(TAG,"收到音频消息。msgId=" + audioMsg.getMessageId() + ", url=" + audioMsg.getFileUrl() + ", duration=" + audioMsg.getDuration());
break;
case -5:
AVIMVideoMessage videoMsg = (AVIMVideoMessage) message;
Log.d(TAG,"收到视频消息。msgId=" + videoMsg.getMessageId() + ", url=" + videoMsg.getFileUrl() + ", duration=" + videoMsg.getDuration());
break;
case -6:
AVIMLocationMessage locMsg = (AVIMLocationMessage)message;
Log.d(TAG,"收到位置消息。msgId=" + locMsg.getMessageId() + ", latitude=" + locMsg.getLocation().getLatitude() + ", longitude=" + locMsg.getLocation().getLongitude());
break;
}
}
};
/**
* 获取最近会话列表
*/
public void getConversations(){
String objectId = AppConfigUtils.getInstance().getLoginInfo(getActivity()).getObjectId();
AVIMClient client = AVIMClient.getInstance(objectId);
AVIMConversationsQuery query = client.getConversationsQuery();
query.setWithLastMessagesRefreshed(true);
query.findInBackground(new AVIMConversationQueryCallback(){
@Override
public void done(List<AVIMConversation> convs, AVIMException e){
if(e==null){
//convs就是获取到的conversation列表
//注意:按每个对话的最后更新日期(收到最后一条消息的时间)倒序排列
Log.e(TAG, "done: 会话大小" +convs.size());
}
}
});
}
会话属性
/**
* 用户退出实时通信服务(断开 LeanCloud 云端服务器连接)时需要在 IMClient
* 对象上调用 AVIMClient.close(AVIMClientCallback cb)。
*/
public void close(){
//关闭通信服务
LoginResponse loginInfo = AppConfigUtils.getInstance().getLoginInfo(app);
if (loginInfo != null && !TextUtils.isEmpty(loginInfo.getObjectId())) {
AVIMClient user = AVIMClient.getInstance(AppConfigUtils.getInstance().getLoginInfo(app).getObjectId());
user.close(new AVIMClientCallback() {
@Override
public void done(AVIMClient avimClient, AVIMException e) {
Log.e(TAG, "done: 退出成功");
}
});
}
}