Android基于环信SDK开发IM即时聊天(一)

2016-09-02更新:可以看一下最新的这篇文章和源码,Android基于环信SDK开发IM即时聊天(二)

目前市面上我了解的做第三方即时聊天SDK的有两家:环信融云,这里我使用环信SDK来完成即时聊天的初步开发工作。

下面先奉上1张效果图:
聊天内容列表
1、开发准备

首先要到环信官网注册开发者账号,目前只有企业账号注册,不过反正也不会去审核企业信息的正确与否,所以随便填写个自己喜欢的ID就好了。注册成功后,登陆到环信管理后台,新建一个应用,环信的appkey就是根据你的应用名和企业ID来确定的,比如我的企业ID叫SIP,应用名叫Luffy,那么我的appkey就是SIP#Luffy,简单好记。
然后需要在IDE(这里我还是使用的Eclipse)中新建一个Android Project,取名叫IMSample,该项目工程代码目前托管在CSDN平台下,传送门
最后在环信SDK官网下载最新的SDK,这样准备工作就完成了。

2、登陆注册

1、初始化SDK

把下载的SDK中的jar包和so文件放在对应目录下,在AndroidManifest.xml中添加appkey声明,然后是在代码中初始化SDK,建议继承Application类,在自己的application中初始化SDK

		int pid = android.os.Process.myPid();
		String processAppName = getAppName(pid);
		if (processAppName == null
				|| !processAppName.equalsIgnoreCase("com.example.imsample")) {
			Log.e(TAG, "enter the service process!");
			return;
		}
		EMChat.getInstance().init(getApplicationContext());

2、注册

注册模式,我选择开放注册,然后在注册界面添加图片验证码功能,降低恶意注册垃圾用户的可能性。

		EMChatManager.getInstance().createAccountOnServer(userName, password);

注册流程
注册成功后,我们可以在环信管理后台中看到刚刚注册的用户,当然我们也可以在后台手动界面化添加注册用户
后台注册用户

3、登陆

登陆
然后回到登陆界面,使用刚刚注册的账号登陆

		EMChatManager.getInstance().login(userName, password, new EMCallBack() {// 回调
					@Override
					public void onSuccess() {
						runOnUiThread(new Runnable() {
							public void run() {
								EMGroupManager.getInstance().loadAllGroups();
								EMChatManager.getInstance()
										.loadAllConversations();
								Toast.makeText(getApplicationContext(), "登陆成功",
										Toast.LENGTH_SHORT).show();
								startActivity(new Intent(
										ChatLoginActivity.this,
										ManiActivity.class));
							}
						});
					}

					@Override
					public void onProgress(int progress, String status) {

					}

					@Override
					public void onError(int code, String message) {
						if (code == -1005) {
							message = "用户名或密码错误";
						}
						final String msg = message;
						runOnUiThread(new Runnable() {
							public void run() {
								Toast.makeText(getApplicationContext(), msg,
										Toast.LENGTH_SHORT).show();
							}
						});
					}
				});

如果下次再进入应用,默认是自动登陆的,当然也可以在application中设置不自动登陆

		EMChat.getInstance().setAutoLogin(false)

不过我们需要在自动登录的地方加入以下代码,不然会获取不到好友列表和会话信息等

		if (EMChat.getInstance().isLoggedIn()) {
			Log.d("TAG", "已经登陆过");
			EMGroupManager.getInstance().loadAllGroups();
			EMChatManager.getInstance().loadAllConversations();
			startActivity(new Intent(ChatLoginActivity.this,
					ManiActivity.class));
		}

4、注销

注销当前登陆用户前,记得清空保存的用户数据

EMChatManager.getInstance().logout(new EMCallBack() {

			@Override
			public void onSuccess() {
				// 跳转到登陆页面
			}

			@Override
			public void onError(int code, String message) {
				// 登出失败

			}

			@Override
			public void onProgress(int progress, String status) {
				// 正在退出
				
			}

		});

3、好友管理

1、好友的添加

根据环信SDK官方开发文档介绍,需要对添加好友作异步处理
这里写图片描述

		try {
			EMContactManager.getInstance().addContact(idStr, reasonStr);
			Log.i("TAG", "请求发送成功,等待对方验证");
		} catch (EaseMobException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Log.i("TAG", "addContact-Errcode==>" + e.getErrorCode());
		}

2、好友申请的同意与拒绝

设置一个好友监听器来监听应用程序中好友的状态,同时告诉EMChat已经初始化完毕,可以开始监听了
这里写图片描述

		EMContactManager.getInstance().setContactListener(
				new MyContactListener());
		EMChat.getInstance().setAppInited();

继承EMContactListener实现的自定义好友监听器监听了五种不同的好友状态变化

	private class MyContactListener implements EMContactListener {

		@Override
		public void onContactAgreed(String username) {
			// 好友请求被同意
			Log.i("TAG", "onContactAgreed==>" + username);
			// 提示有新消息
			EMNotifier.getInstance(getApplicationContext()).notifyOnNewMsg();
			Toast.makeText(getApplicationContext(), username + "同意了你的好友请求",
					Toast.LENGTH_SHORT).show();
		}

		@Override
		public void onContactRefused(String username) {
			// 好友请求被拒绝
			Log.i("TAG", "onContactRefused==>" + username);
		}

		@Override
		public void onContactInvited(String username, String reason) {
			// 收到好友添加请求
			Log.i("TAG", username + "onContactInvited==>" + reason);
			showAgreedDialog(username, reason);
			EMNotifier.getInstance(getApplicationContext()).notifyOnNewMsg();
		}

		@Override
		public void onContactDeleted(List<String> usernameList) {
			// 好友被删除时回调此方法
			Log.i("TAG", "usernameListDeleted==>" + usernameList.size());
		}

		@Override
		public void onContactAdded(List<String> usernameList) {
			// 添加了新的好友时回调此方法
			for (String str : usernameList) {
				Log.i("TAG", "usernameListAdded==>" + str);
			}
		}
	}

对于好友申请的同意或者拒绝只需要一行代码,和上面第二步的好友添加一样,需要添加异步处理,之后记得刷新当前好友列表

EMChatManager.getInstance().acceptInvitation(user); // 同意
EMChatManager.getInstance().refuseInvitation(user); // 拒绝 

3、好友列表的获取

获取好友列表只能获取到好友的名字(id),如果想获取到每个好友的详细信息,还得再重新调取其他接口,在我的demo里,也不用获取到好友详细信息
这里写图片描述

List<String> userList = EMContactManager.getInstance().getContactUserNames();

4、好友的删除

长按好友列表某一项可以删除好友,删除好友和前面几步的添加、同意、拒绝一样,需要异步处理和刷新列表

EMChatManager.getInstance().deleteContact(user); // 删除

4、即时聊天

点击好友列表即可发起聊天请求,效果图见文章开头,四步走
第一:新建一个继承自BroadcastReceiver的用来接收新消息的广播

	private class NewMessageBroadcastReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			// 注销广播
			abortBroadcast();

			// 消息id(每条消息都会生成唯一的一个id,目前是SDK生成)
			String msgId = intent.getStringExtra("msgid");
			// 发送方
			String username = intent.getStringExtra("from");
			// 收到这个广播的时候,message已经在db和内存里了,可以通过id获取mesage对象
			EMMessage message = EMChatManager.getInstance().getMessage(msgId);
			EMConversation conversation = EMChatManager.getInstance()
					.getConversation(username);
			
			MessageBody tmBody = message.getBody();

			ChatListData data = new ChatListData();
			data.setReceiveContent(((TextMessageBody) tmBody).getMessage());
			data.setType(2);
			mListData.add(data);
			mHandler.sendEmptyMessage(0x00001);

			Log.i("TAG", "收到消息:" + ((TextMessageBody) tmBody).getMessage());
			// 如果是群聊消息,获取到group id
			if (message.getChatType() == ChatType.GroupChat) {
				username = message.getTo();
			}

			if (!username.equals(username)) {
				// 消息不是发给当前会话,return
				return;
			}
		}
	}

第二:在该类入口处注册这个广播以及环信的intentFilter

		msgReceiver = new NewMessageBroadcastReceiver();
		IntentFilter intentFilter = new IntentFilter(EMChatManager
				.getInstance().getNewMessageBroadcastAction());
		intentFilter.setPriority(3);
		registerReceiver(msgReceiver, intentFilter);

第三:在发送消息按钮的监听方法里发送聊天消息

	void sendMessageHX(String username, final String content) {
		// 获取到与聊天人的会话对象。参数username为聊天人的userid或者groupid,后文中的username皆是如此
		EMConversation conversation = EMChatManager.getInstance()
				.getConversation(username);
		// 创建一条文本消息
		EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
		// // 如果是群聊,设置chattype,默认是单聊
		// message.setChatType(ChatType.GroupChat);
		// 设置消息body
		TextMessageBody txtBody = new TextMessageBody(content);
		message.addBody(txtBody);
		// 设置接收人
		message.setReceipt(username);
		// 把消息加入到此会话对象中
		conversation.addMessage(message);
		// 发送消息
		EMChatManager.getInstance().sendMessage(message, new EMCallBack() {

			@Override
			public void onError(int arg0, String arg1) {
				// TODO Auto-generated method stub
				Log.i("TAG", "消息发送失败");
			}

			@Override
			public void onProgress(int arg0, String arg1) {
				// TODO Auto-generated method stub
				Log.i("TAG", "正在发送消息");
			}

			@Override
			public void onSuccess() {
				// TODO Auto-generated method stub
				Log.i("TAG", "消息发送成功");
				ChatListData data = new ChatListData();
				data.setSendContent(content);
				data.setType(1);
				mListData.add(data);
				mHandler.sendEmptyMessage(0x00001);
			}
		});
	}

第四:在该类的onDestory()方法里注销这个广播

@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unregisterReceiver(msgReceiver);

	}

5、总结

感觉环信SDK还是不太稳定,或者也有可能说是我没用好,这里这是简单的介绍下它的功能,在我的demo里仅仅简单实现了这样几个功能:
1,开放注册,登陆
2,好友添加、同意与拒绝(重新登陆才能看到)、删除,列表获取
3,只有双方都在聊天会话界面才能即时聊天
还有几个大问题没解决或者说需要重度优化:
1,断线重连
2,离线消息的保存与读取
3,好友添加请求与响应请求的即时显示
4,好友列表消息数目的获取显示
5,会话列表中消息的滚动位置及未读消息提示等

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值