消息


可以发送文本消息和表情、语音消息、图片消息、地理位置消息以及文件消息。

发送文本消息及表情

//获取到与聊天人的会话对象。参数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(){});

发送语音消息

EMConversation conversation = EMChatManager.getInstance().getConversation(username);
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.VOICE);
//如果是群聊,设置chattype,默认是单聊
message.setChatType(ChatType.GroupChat);
VoiceMessageBody body = new VoiceMessageBody(new File(filePath), len);
message.addBody(body);
message.setReceipt(username);
conversation.addMessage(message);
EMChatManager.getInstance().sendMessage(message, new EMCallBack(){});

发送图片消息

EMConversation conversation = EMChatManager.getInstance().getConversation(username);
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.IMAGE);
//如果是群聊,设置chattype,默认是单聊
message.setChatType(ChatType.GroupChat);

ImageMessageBody body = new ImageMessageBody(new File(filePath));
// 默认超过100k的图片会压缩后发给对方,可以设置成发送原图
// body.setSendOriginalImage(true);
message.addBody(body);
message.setReceipt(username);
conversation.addMessage(message);
EMChatManager.getInstance().sendMessage(message, new EMCallBack(){});

发送地理位置消息

EMConversation conversation = EMChatManager.getInstance().getConversation(username);
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.LOCATION);
//如果是群聊,设置chattype,默认是单聊
message.setChatType(ChatType.GroupChat);
LocationMessageBody locBody = new LocationMessageBody(locationAddress, latitude, longitude);
message.addBody(locBody);
message.setReceipt(username);
conversation.addMessage(message);
EMChatManager.getInstance().sendMessage(message, new EMCallBack(){});

发送文件消息

EMConversation conversation = EMChatManager.getInstance().getConversation(username);
// 创建一个文件消息
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.FILE);
// 如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
	message.setChatType(ChatType.GroupChat);
//设置接收人的username
message.setReceipt(username);
// add message body
NormalFileMessageBody body = new NormalFileMessageBody(new File(filePath));
message.addBody(body);
conversation.addMessage(message);
EMChatManager.getInstance().sendMessage(message, new EMCallBack(){});

发送透传消息

透传消息能做什么:头像、昵称的更新等,可以把透传消息理解为一条指令,通过发送这条指令给对方,告诉对方要做的 action,收到消息可以自定义处理的一种消息。(透传消息不会存入本地数据库中,所以在 UI 上是不会显示的。)

透传消息发送格式

EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);

//支持单聊和群聊,默认单聊,如果是群聊添加下面这行
cmdMsg.setChatType(ChatType.GroupChat)

String action="action1";//action可以自定义,在广播接收时可以收到
CmdMessageBody cmdBody=new CmdMessageBody(action);
String toUsername="test1";//发送给某个人
cmdMsg.setReceipt(toUsername);
cmdMsg.setAttribute("a", "a");//支持自定义扩展
cmdMsg.addBody(cmdBody); 
EMChatManager.getInstance().sendMessage(cmdMsg, new EMCallBack());

CMD 消息广播监听

// 注册一个cmd消息的BroadcastReceiver
	IntentFilter cmdIntentFilter = new IntentFilter(EMChatManager.getInstance().getCmdMessageBroadcastAction());
	mContext.registerReceiver(cmdMessageReceiver, cmdIntentFilter);
	
    /**
	 * cmd消息BroadcastReceiver
	 */
	private BroadcastReceiver cmdMessageReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			//获取cmd message对象
			String msgId = intent.getStringExtra("msgid");
			EMMessage message = intent.getParcelableExtra("message");
			//获取消息body
			CmdMessageBody cmdMsgBody = (CmdMessageBody) message.getBody();
			String aciton = cmdMsgBody.action;//获取自定义action
			//获取扩展属性
			String attr=message.getStringAttribute("a");
		}
	};

发送扩展消息

当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。

//这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。
EMMessage message = EMMessage.createSendMessage(EMMessage.Type.TXT);
TextMessageBody txtBody = new TextMessageBody(content);
message.addBody(txtBody);

// 增加自己特定的属性,目前SDK支持int、boolean、String这三种属性,可以设置多个扩展属性
message.setAttribute("attribute1", "value");
message.setAttribute("attribute2", true);
...

message.setReceipt(username);
conversation.addMessage(message);
//发送消息
EMChatManager.getInstance().sendMessage(message, new EMCallBack(){});

//在接收消息的BroadcastReceive中,通过自己设置的key即可取到这些value
private class NewMessageBroadcastReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		// 消息id
		String msgId = intent.getStringExtra("msgid"); 
		//根据消息id获取message
		EMMessage message = EMChatManager.getInstance().getMessage(msgId);
		//获取自定义的属性,第2个参数为返回的默认值
		message.getStringAttribute("attribute1",null);
		message.getBooleanAttribute("attribute2", false);
                ...
                
		abortBroadcast();
	}
}

通过广播接收新消息

注意事项:为了防止新消息来时,因为没有注册广播接收者,导致漏接消息的情况,注册完接受者以及好友监听等事件后,需要调用以下 SDK 才会发送新消息的广播,只需调用一次即可,可参考 Demo 的 mainactivity。

EMChat.getInstance().setAppInited()

另外,当 APP 在后台时,SDK 默认以 notification 的形式通知有新消息,不会走广播,如果需要走广播,可以调用以下 SDK 关闭 notification 通知,这样新消息还是走发送广播的形式。

EMChatManager.getInstance().getChatOptions().setShowNotificationInBackgroud(false)

注册一个相应 broadcast,用来接收消息。

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

private class NewMessageBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //消息id
        String msgId = intent.getStringExtra("msgid");
        //发消息的人的username(userid)
        String msgFrom = intent.getStringExtra("from");
        //消息类型,文本、图片、语音消息等,这里返回的值为msg.type.ordinal()。
        //所以消息type实际为是enum类型
        int msgType = intent.getIntExtra("type", 0);
        Log.d("main", "new message id:" + msgId + " from:" + msgFrom + " type:" + msgType);
        //更方便的方法是通过msgId直接获取整个message
        EMMessage message = EMChatManager.getInstance().getMessage(msgId);
        }
}

通过监听事件来接收新消息

注意事项:注册消息事件监听,此 listener 会收到所有类型的 event 事件,如果对某种或某些类型的事件感兴趣,可以用 registerEventListener(EMEventListener listener, EMNotifierEvent.EventType[] types)。

EMNotifierEvent.Event.EventDeliveryAck;//已发送回执event注册
EMNotifierEvent.Event.EventNewCMDMessage;//接收透传event注册
EMNotifierEvent.Event.EventNewMessage;//接收新消息event注册
EMNotifierEvent.Event.EventOfflineMessage;//接收离线消息event注册
EMNotifierEvent.Event.EventReadAck;//已读回执event注册
EMNotifierEvent.Event.EventConversationListChanged;//通知会话列表通知event注册(在某些特殊情况,SDK去删除会话的时候会收到回调监听)

接收所有的 event 事件:

EMChatManager.getInstance().registerEventListener(new EMEventListener() {
			
	@Override
	public void onEvent(EMNotifierEvent event) {
		// TODO Auto-generated method stub
		EMMessage message = (EMMessage) event.getData();
	}
});

有选择性的接收某些类型 event 事件:

EMChatManager.getInstance().registerEventListener(new EMEventListener() {
			
	@Override
	public void onEvent(EMNotifierEvent event) {
		// TODO Auto-generated method stub
		EMMessage message = (EMMessage) event.getData();
	}
	}, new EMNotifierEvent.Event[]{EMNotifierEvent.Event.EventNewMessage,.......}
);

注:广播和监听事件不可同时混用。

解除监听事件

如果不想收到回调,则执行解除监听事件。

EMChatManager.getInstance().unregisterEventListener(new EMEventListener() {
			
	@Override
	public void onEvent(EMNotifierEvent event) {
		// TODO Auto-generated method stub
		
	}
});

获取聊天记录

EMConversation conversation = EMChatManager.getInstance().getConversation(username|groupid);
//获取此会话的所有消息
List<EMMessage> messages = conversation.getAllMessages();
//sdk初始化加载的聊天记录为20条,到顶时需要去db里获取更多
//获取startMsgId之前的pagesize条消息,此方法获取的messages sdk会自动存入到此会话中,app中无需再次把获取到的messages添加到会话中
List<EMMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize);
//如果是群聊,调用下面此方法
List<EMMessage> messages = conversation.loadMoreGroupMsgFromDB(startMsgId, pagesize);

获取未读消息数量

EMConversation conversation = EMChatManager.getInstance().getConversation(username|groupid);
conversation.getUnreadMsgCount();

未读消息数清零

指定会话消息未读数清零。

EMConversation conversation = EMChatManager.getInstance().getConversation(username|groupid);
conversation.markAllMessagesAsRead();

所有未读消息数清零

EMChatManager.getInstance().markAllConversationsAsRead();

获取消息总数

EMConversation conversation = EMChatManager.getInstance().getConversation(username|groupid);
    conversation.getMsgCount();

清空会话聊天记录

//清空和某个user的聊天记录(包括本地),不删除conversation这个会话对象
EMChatManager.getInstance().clearConversation(username|groupid);

删除单个聊天记录

//删除和某个user的整个的聊天记录(包括本地)
EMChatManager.getInstance().deleteConversation(username|groupid);
//删除当前会话的某条聊天记录
EMConversation conversation = EMChatManager.getInstance().getConversation(username|groupid);
conversation.removeMessage(deleteMsg.msgId);

删除所有聊天记录

//删除所有会话记录(包括本地)
EMChatManager.getInstance().deleteAllConversation();

设置某条消息为已读

//markAsRead为true,则标记msgid的消息位已读
  conversation.getMessage({msgid},markAsRead);

设置自定义的消息提示

APP 在后台时,新消息会通过 notification 的方式,在手机状态栏提示新消息,可以把提示的内容换成自定义的内容(在application的oncreate()里设置)。

//获取到配置options对象
EMChatOptions options = EMChatManager.getInstance().getChatOptions();
//设置自定义的文字提示
options.setNotifyText(new OnMessageNotifyListener() {
	
	@Override
	public String onNewMessageNotify(EMMessage message) {
		//可以根据message的类型提示不同文字,这里为一个简单的示例
		return "你的好基友" + message.getFrom() + "发来了一条消息哦";
	}
	
	@Override
	public String onLatestMessageNotify(EMMessage message, int fromUsersNum, int messageNum) {
		return fromUsersNum + "个基友,发来了" + messageNum + "条消息";
	}
});

设置自定义 notification 点击跳转 intent。

用户点击 notification 消息,SDK 会有默认的跳转 intent,开发者可以设置自己的跳转 intent,这里以 UIdemo 的代码为例。

// 获取到EMChatOptions对象
EMChatOptions options = EMChatManager.getInstance().getChatOptions();
//设置notification点击listener
options.setOnNotificationClickListener(new OnNotificationClickListener() {

	@Override
	public Intent onNotificationClick(EMMessage message) {
		Intent intent = new Intent(applicationContext, ChatActivity.class);
		ChatType chatType = message.getChatType();
		if(chatType == ChatType.Chat){ //单聊信息
			intent.putExtra("userId", message.getFrom());
			intent.putExtra("chatType", ChatActivity.CHATTYPE_SINGLE);
		}else{ //群聊信息
			//message.getTo()为群聊id
			intent.putExtra("groupId", message.getTo());
			intent.putExtra("chatType", ChatActivity.CHATTYPE_GROUP);
		}
		return intent;
	}
});

SDK 中提供了方便的新消息提醒功能。可以在收到消息时调用,提醒用户有新消息。

首先获取EMChatOptions。

chatOptions = EMChatManager.getInstance().getChatOptions();

设置是否启用新消息提醒(打开或者关闭消息声音和震动提示)。

chatOptions.setNotifyBySoundAndVibrate(true|false); //默认为true 开启新消息提醒

设置是否启用新消息声音提醒。

chatOptions.setNoticeBySound(true|false); //默认为true 开启声音提醒

设置是否启用新消息震动提醒。

chatOptions.setNoticedByVibrate(true|false); //默认为true 开启震动提醒

设置语音消息播放是否设置为扬声器播放。

chatOptions.setUseSpeaker(true|false); //默认为true 开启扬声器播放

设置后台接收新消息时是否通过通知栏提示。

chatOptions.setShowNotificationInBackgroud(true|false) //默认为true

附:

chatOptions.setAcceptInvitationAlways(false); 

//默认添加好友时为true,是不需要验证的,改成需要验证为false

导入消息到环信DB。

//创建一条发送TextMsg
 private EMMessage createSentTextMsg(String to) {
		EMMessage msg = EMMessage.createSendMessage(Type.TXT);
		TextMessageBody body = new TextMessageBody("send text msg " + System.currentTimeMillis());
		msg.addBody(body);
		msg.setTo(to);
		msg.setFrom(CURRENTUSER);
		msg.setMsgTime(System.currentTimeMillis());
		return msg;
 }

 //创建一条接收TextMsg
 private EMMessage createReceivedTextMsg(String from) {
		EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
		TextMessageBody body = new TextMessageBody("receive text msg " + System.currentTimeMillis());
		msg.addBody(body);
		msg.setFrom(from);
		msg.setTo(CURRENTUSER);
		msg.setMsgTime(System.currentTimeMillis());
		return msg;
 }
 //import single chat
  EMMessage msg1 = createSentTextMsg("jma1");
  EMChatManager.getInstance().importMessage(msg1, false);
  EMMessage msg2 = createReceivedTextMsg(getRadomUserName());
  EMChatManager.getInstance().importMessage(msg2, false);
 //import group chat 
 
 //导入群聊消息和单聊消息类似,按照如下修改即可
 //只需要指定msg.setChatType(ChatType.GroupChat)
 //然后把目标username传入groupid即可

下载 Demo 及 SDK

详细文档请参考 Java doc


下一页:好友管理