安卓环信sdk,环信发送消息成功回调怎么发不出去

Android SDK 基础功能
SDK 中相关异步/同步处理方法介绍
同步方法:SDK 里大部分方法都为同步方法,即这个方法执行完毕,才会走后面的代码。
异步方法:带有 callback 以及 API 注释里明确写明异步方法的方法,即不需要等这个方法走完,后边的代码就已经在执行了,通过 callback 得到方法执行的结果。
以Demo为例,获取本地的log
adb pull /sdcard/Android/data/com.hyphenate.chatuidemo/easemob-demo#chatdemoui/core_log/easemob.log
其中com.hyphenate.chatuidemo是packagename, easemob-demo#chatdemoui是appkey,需要替换成自己对应的路径。
初始化 SDK
要求在 application 的oncreate方法中做初始化,初始化的时候需要传入设置好的 options。
EMOptions options = new EMOptions();
// 默认添加好友时,是不需要验证的,改成需要验证
options.setAcceptInvitationAlways(false);
// 是否自动将消息附件上传到环信服务器,默认为True是使用环信服务器上传下载,如果设为 false,需要开发者自己处理附件消息的上传和下载
options.setAutoTransferMessageAttachments(true);
// 是否自动下载附件类消息的缩略图等,默认为 true 这里和上边这个参数相关联
options.setAutoDownloadThumbnail(true);
EMClient.getInstance().init(applicationContext, options);
//在做打包混淆时,关闭debug模式,避免消耗不必要的资源
EMClient.getInstance().setDebugMode(true);
注:如果你的 APP 中有第三方的服务启动,请在初始化 SDK(EMClient.getInstance().init(applicationContext, options))方法的前面添加以下相关代码(相应代码也可参考 Demo 的 application),使用 EaseUI 库的就不用理会这个。
appContext =
int pid = android.os.Process.myPid();
String processAppName = getAppName(pid);
// 如果APP启用了远程的service,此application:onCreate会被调用2次
// 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次
// 默认的APP会在以包名为默认的process name下运行,如果查到的process name不是APP的process name就立即返回
if (processAppName == null ||!processAppName.equalsIgnoreCase(appContext.getPackageName())) {
Log.e(TAG, &enter the service process!&);
// 则此application::onCreate 是被service 调用的,直接返回
如何获取processAppName请参考以下方法。
private String getAppName(int pID) {
String processName =
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = this.getPackageManager();
while (i.hasNext()) {
ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
if (info.pid == pID) {
processName = info.processN
return processN
} catch (Exception e) {
// Log.d(&Process&, &Error&& :&+ e.toString());
return processN
注册模式分两种,开放注册和授权注册。只有开放注册时,才可以客户端注册。
开放注册是为了测试使用,正式环境中不推荐使用该方式注册环信账号;
授权注册的流程应该是您服务器通过环信提供的 REST API 注册,之后保存到您的服务器或返回给客户端。
注册用户名会自动转为小写字母,所以建议用户名均以小写注册。(强烈建议开发者通过后台调用 REST 接口去注册环信 ID,客户端注册方法不提倡使用。)
//注册失败会抛出HyphenateException
EMClient.getInstance().createAccount(username, pwd);//同步方法
注意: 登录成功后需要调用EMClient.getInstance().chatManager().loadAllConversations(); 和EMClient.getInstance().groupManager().loadAllGroups();。
以上两个方法是为了保证进入主页面后本地会话和群组都 load 完毕。
另外如果登录过,APP 长期在后台再进的时候也可能会导致加载到内存的群组和会话为空,可以在主页面的 oncreate 里也加上这两句代码,当然,更好的办法应该是放在程序的开屏页,可参考 Demo 的 SplashActivity。
EMClient.getInstance().login(userName,password,new EMCallBack() {//回调
public void onSuccess() {
EMClient.getInstance().groupManager().loadAllGroups();
EMClient.getInstance().chatManager().loadAllConversations();
Log.d(&main&, &登录聊天服务器成功!&);
public void onProgress(int progress, String status) {
public void onError(int code, String message) {
Log.d(&main&, &登录聊天服务器失败!&);
即首次登录成功后,不需要再次调用登录方法,在下次 APP 启动时,SDK 会自动为您登录。并且如果您自动登录失败,也可以读取到之前的会话信息(以上情况是在未调用登出的情况下实现的)。
SDK 中自动登录属性默认是 true 打开的,如果不需要自动登录,在初始化 SDK 初始化的时候,调用options.setAutoLogin(false);设置为 false 关闭。
自动登录在以下几种情况下会被取消:
用户调用了 SDK 的登出动作;
用户在别的设备上更改了密码,导致此设备上自动登录失败;
用户的账号被从服务器端删除;
用户从另一个设备登录,把当前设备上登录的用户踢出。
EMClient.getInstance().logout(true);
EMClient.getInstance().logout(true, new EMCallBack() {
public void onSuccess() {
// TODO Auto-generated method stub
public void onProgress(int progress, String status) {
// TODO Auto-generated method stub
public void onError(int code, String message) {
// TODO Auto-generated method stub
如果集成了GCM等第三方推送,方法里第一个参数需要设为true,这样退出的时候会解绑设备token,否则可能会出现退出了,还能收到消息的现象。
有时候可能会碰到网络问题而解绑失败,app处理时可以弹出提示框让用户选择,是否继续退出(弹出框提示继续退出能收到消息的风险),如果用户选择继续退出,传false再调用logout方法退出成功;
当然也可以失败后还是返回退出成功,然后在后台起个线程不断调用logout方法直到成功,这样有个风险是:用户kill了app,然后网络恢复,用户还是会继续收到消息。
还有一个需要注意的是:如果调用异步退出方法,在收到onsucess的回调后才去调用IM相关的方法,比如login
注册连接状态监听
当掉线时,Android SDK 会自动重连,无需进行任何操作,通过注册连接监听来知道连接状态。
在聊天过程中难免会遇到网络问题,在此 SDK 为您提供了网络监听接口,实时监听
可以根据 disconnect 返回的 error 判断原因。若服务器返回的参数值为EMError.USER_LOGIN_ANOTHER_DEVICE,则认为是有同一个账号异地登录;若服务器返回的参数值为EMError.USER_REMOVED,则是账号在后台被删除。
//注册一个监听连接状态的listener
EMClient.getInstance().addConnectionListener(new MyConnectionListener());
//实现ConnectionListener接口
private class MyConnectionListener implements EMConnectionListener {
public void onConnected() {
public void onDisconnected(final int error) {
runOnUiThread(new Runnable() {
public void run() {
if(error == EMError.USER_REMOVED){
// 显示帐号已经被移除
}else if (error == EMError.USER_LOGIN_ANOTHER_DEVICE) {
// 显示帐号在其他设备登录
if (NetUtils.hasNetwork(MainActivity.this))
//连接不到聊天服务器
//当前网络不可用,请检查网络设置4被浏览423分享邀请回答2添加评论分享收藏感谢收起错误代码:&error code=&404& type=&cancel&&
&item-not-found xmlns=&urn:ietf:params:xml:ns:xmpp-stanzas&/&
&text xmlns=&urn:ietf:params:xml:ns:xmpp-stanzas&&Conference room does not exist&/text&
1、消息是怎么发的?
2、断点看下发送失败的errorcode是什么?
3、你发送的消息类型是什么?单聊,群聊还是聊天室?
1.消息发送方法NSDictionary *ext =
EMMessage *tempMessage = [ChatSendHelper sendTextMessageWithString:textMessage
toUsername:_conversation.chatter
messageType:[self messageType]
requireEncryption:NO
[self addMessage:tempMessage];
EMErrorNotFound
3.发送的消息类型是群聊
1、你上面发的这个不是sdk发消息的方法,看下下面这段代码,
EMMessage *message = [[EaseMob sharedInstance].chatManager
asyncSendMessage:retureMsg
progress:nil];这句才是发消息的接口。
// 发送消息
+(EMMessage *)sendMessage:(NSString *)username
messageBody:(id&IEMMessageBody&)body
messageType:(EMMessageType)type
requireEncryption:(BOOL)requireEncryption
ext:(NSDictionary *)ext
EMMessage *retureMsg = [[EMMessage alloc] initWithReceiver:username
bodies:@[body]];
retureMsg.requireEncryption = requireE
retureMsg.messageType =
retureMsg.ext =
EMMessage *message = [[EaseMob sharedInstance].chatManager
asyncSendMessage:retureMsg
progress:nil];
2、断点看下你message里面的各个参数都有没有问题,群组id是不是对的。
这个里面的参数都是没有问题的,群组id也没有问题,是不是哪里配置错了
你这个error,EMErrorNotFound,是从哪里打印的?
明天再给你发具体的吧
Conference room does not exis,提示是不存在,新建一个群试一下
申请试用 提交后工作人员会尽快与您联系进行功能演示
提交 不了,谢谢
技术咨询已转移到管理后台,请先登录 即时通讯云使用者请在应用详情页面咨询客户互动云使用者请进入管理员模式咨询发送文本、语音、图片、位置等消息(单聊/群聊通用)。
发送文本消息
//创建一条文本消息,content为消息文字内容,toChatUsername为对方用户或者群聊的id,后文皆是如此
EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername);
//如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
//发送消息
EMClient.getInstance().chatManager().sendMessage(message);
发送语音消息
//filePath为语音文件路径,length为录音时间(秒)
EMMessage message = EMMessage.createVoiceSendMessage(filePath, length, toChatUsername);
//如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
发送视频消息
//videoPath为视频本地路径,thumbPath为视频预览图路径,videoLength为视频时间长度
EMMessage message = EMMessage.createVideoSendMessage(videoPath, thumbPath, videoLength, toChatUsername);
//如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
发送图片消息
//imagePath为图片本地路径,false为不发送原图(默认超过100k的图片会压缩后发给对方),需要发送原图传true
EMMessage.createImageSendMessage(imagePath, false, toChatUsername);
//如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
发送地理位置消息
//latitude为纬度,longitude为经度,locationAddress为具体位置内容
EMMessage message = EMMessage.createLocationSendMessage(latitude, longitude, locationAddress, toChatUsername);
//如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
发送文件消息
EMMessage message = EMMessage.createFileSendMessage(filePath, toChatUsername);
// 如果是群聊,设置chattype,默认是单聊
if (chatType == CHATTYPE_GROUP)
message.setChatType(ChatType.GroupChat);
EMClient.getInstance().chatManager().sendMessage(message);
发送透传消息
透传消息能做什么:头像、昵称的更新等。可以把透传消息理解为一条指令,通过发送这条指令给对方,告诉对方要做的 action,收到消息可以自定义处理的一种消息。(透传消息不会存入本地数据库中,所以在 UI 上是不会显示的)
EMMessage cmdMsg = EMMessage.createSendMessage(EMMessage.Type.CMD);
//支持单聊和群聊,默认单聊,如果是群聊添加下面这行
cmdMsg.setChatType(ChatType.GroupChat)
String action=&action1&;//action可以自定义
EMCmdMessageBody cmdBody = new EMCmdMessageBody(action);
String toUsername = &test1&;//发送给某个人
cmdMsg.setTo(toUsername);
cmdMsg.addBody(cmdBody);
EMClient.getInstance().chatManager().sendMessage(cmdMsg);
发送扩展消息
当 SDK 提供的消息类型不满足需求时,开发者可以通过扩展自 SDK 提供的文本、语音、图片、位置等消息类型,从而生成自己需要的消息类型。
这里是扩展自文本消息,如果这个自定义的消息需要用到语音或者图片等,可以扩展自语音、图片消息,亦或是位置消息。
EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername);
// 增加自己特定的属性
message.setAttribute(&attribute1&, &value&);
message.setAttribute(&attribute2&, true);
EMClient.getInstance().chatManager().sendMessage(message);
//接收消息的时候获取到扩展属性
//获取自定义的属性,第2个参数为没有此定义的属性时返回的默认值
message.getStringAttribute(&attribute1&,null);
message.getBooleanAttribute(&attribute2&, false);
通过注册消息监听来接收消息。
EMClient.getInstance().chatManager().addMessageListener(msgListener);
EMMessageListener msgListener = new EMMessageListener() {
public void onMessageReceived(List&EMMessage& messages) {
//收到消息
public void onCmdMessageReceived(List&EMMessage& messages) {
//收到透传消息
public void onMessageRead(List&EMMessage& messages) {
//收到已读回执
public void onMessageDelivered(List&EMMessage& message) {
//收到已送达回执
public void onMessageRecalled(List&EMMessage& messages) {
//消息被撤回
public void onMessageChanged(EMMessage message, Object change) {
//消息状态变动
记得在不需要的时候移除listener,如在activity的onDestroy()时
EMClient.getInstance().chatManager().removeMessageListener(msgListener);
监听消息状态
通过 message 设置消息的发送及接收状态。
message.setMessageStatusCallback(new EMCallBack(){});
获取聊天记录
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
//获取此会话的所有消息
List&EMMessage& messages = conversation.getAllMessages();
//SDK初始化加载的聊天记录为20条,到顶时需要去DB里获取更多
//获取startMsgId之前的pagesize条消息,此方法获取的messages SDK会自动存入到此会话中,APP中无需再次把获取到的messages添加到会话中
List&EMMessage& messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize);
建议初始化SDK的时候设置成每个会话默认load一条消息,节省加载会话的时间,方法为:
options.setNumberOfMessagesLoaded(1);
获取未读消息数量
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
conversation.getUnreadMsgCount();
未读消息数清零
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
//指定会话消息未读数清零
conversation.markAllMessagesAsRead();
//把一条消息置为已读
conversation.markMessageAsRead(messageId);
//所有未读消息数清零
EMClient.getInstance().chatManager().markAllConversationsAsRead();
获取消息总数
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
//获取此会话在本地的所有的消息数量
conversation.getAllMsgCount();
//如果只是获取当前在内存的消息数量,调用
conversation.getAllMessages().size();
环信sdk 在3.3.4版本增加了一个消息漫游接口,即可以从服务器拉取历史消息到本地,方便用户切换设备同步消息(此功能属于增值服务,需要联系商务同事开通)
此方法属于EMChatManager 类,通过EMClient.getInstance().chatManager()调用,使用方法参考 Demo 中 EaseChatFragment 类的 loadMoreRoamingMessages() 方法
* 从服务器获取历史消息
* @param conversationId 会话名称
* @param type 会话类型
* @param pageSize 获取的页面大小
* @param startMsgId 漫游消息的开始消息id,如果为空,从最新的消息向前开始获取
* @return 返回消息列表和用于继续获取历史消息的Cursor
public EMCursorResult&EMMessage& fetchHistoryMessages(String conversationId, EMConversationType type, int pageSize,String startMsgId);
* 从服务器获取历史消息
* @param conversationId 会话名称
* @param type 会话类型
* @param pageSize 获取的页面大小
* @param startMsgId 漫游消息的开始消息id,如果为空,从最新的消息向前开始获取
* @param callBack 返回消息列表和用于继续获取历史消息的Cursor
public void asyncFetchHistoryMessage(String conversationId, EMConversationType type, int pageSize, String startMsgId, EMValueCallBack&EMCursorResult&EMMessage&& callBack)
撤回消息功能
消息撤回功能可以撤回一定时间内发送出去的消息,目前只能是两分钟,不能修改(此功能属于增值服务,需要联系商务同事开通)
EMClient.getInstance().chatManager().recallMessage(contextMenuMessage);
分页获取历史消息记录
EMClient.getInstance().chatManager().fetchHistoryMessages(
toChatUsername, EaseCommonUtils.getConversationType(chatType), pagesize, &&);
final List&EMMessage& msgs = conversation.getAllMessages();
int msgCount = msgs != null ? msgs.size() : 0;
if (msgCount & conversation.getAllMsgCount() && msgCount & pagesize) {
String msgId =
if (msgs != null && msgs.size() & 0) {
msgId = msgs.get(0).getMsgId();
conversation.loadMoreMsgFromDB(msgId, pagesize - msgCount);
messageList.refreshSelectLast();
} catch (HyphenateException e) {
e.printStackTrace();
获取所有会话
Map&String, EMConversation& conversations = EMClient.getInstance().chatManager().getAllConversations();
如果出现偶尔返回的conversations的sizi为0,那很有可能是没有调用EMClient.getInstance().chatManager().loadAllConversations(),或者调用顺序不对,具体用法请参考章节。
删除会话及聊天记录
//删除和某个user会话,如果需要保留聊天记录,传false
EMClient.getInstance().chatManager().deleteConversation(username, true);
//删除当前会话的某条聊天记录
EMConversation conversation = EMClient.getInstance().chatManager().getConversation(username);
conversation.removeMessage(deleteMsg.msgId);
导入消息到数据库
EMClient.getInstance().chatManager().importMessages(msgs);
Demo 及 SDK 下载
详细文档请参考您还没有登录,快捷通道只有在登录后才能使用。 还没有帐号? 赶紧
1共10页10) ? 10 :
location='https://bbs.aliyun.com/detail/342788.html?page='+page+'';}">10) ? 10 :
location='https://bbs.aliyun.com/detail/342788.html?page='+page+'';">Go
android 环信 集成发送消息崩溃
在线时间0小时
小弟集成一下安卓环信sdk
然后用了demo
但是发送消息时候或者接受消息
bugly 提示是一个jar包需要升级
但是 我已然是更高的版本了了
下面是错误消息 希望大神帮忙看一下java.lang.RuntimeException Picasso detected an unsupported OkHttp on the classpath. To use OkHttp with this version of Picasso, you'll need: 1. com.squareup.okhttp:okhttp:1.6.0 (or newer) 2. com.squareup.okhttp:okhttp-urlconnection:1.6.0 (or newer) Note that OkHttp 2.0.0+ is supported!com.squareup.picasso.Utils.createDefaultDownloader(Utils.java:251)com.squareup.picasso.Picasso$Builder.build(Picasso.java:754)com.squareup.picasso.Picasso.with(Picasso.java:597)com.easemob.chatuidemo.utils.UserUtils.setUserAvatar(UserUtils.java:43)com.easemob.chatuidemo.adapter.MessageAdapter.setUserAvatar(MessageAdapter.java:570)com.easemob.chatuidemo.adapter.MessageAdapter.getView(MessageAdapter.java:461)android.widget.AbsListView.obtainView(AbsListView.java:2257)android.widget.ListView.makeAndAddView(ListView.java:1790)android.widget.ListView.fillSpecific(ListView.java:1337)android.widget.ListView.layoutChildren(ListView.java:1620)android.widget.AbsListView.onLayout(AbsListView.java:2089)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:562)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)android.widget.FrameLayout.onLayout(FrameLayout.java:388)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)android.widget.LinearLayout.onLayout(LinearLayout.java:1434)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)android.widget.FrameLayout.onLayout(FrameLayout.java:388)android.view.View.layout(View.java:14828)android.view.ViewGroup.layout(ViewGroup.java:4631)android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2026)android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1783)android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1039)android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5648)android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)android.view.Choreographer.doCallbacks(Choreographer.java:574)android.view.Choreographer.doFrame(Choreographer.java:544)android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)android.os.Handler.handleCallback(Handler.java:733)android.os.Handler.dispatchMessage(Handler.java:95)android.os.Looper.loop(Looper.java:136)android.app.ActivityThread.main(ActivityThread.java:5052)java.lang.reflect.Method.invokeNative(Native Method)java.lang.reflect.Method.invoke(Method.java:515)com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)dalvik.system.NativeStart.main(Native Method)
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
1共10页10) ? 10 :
location='https://bbs.aliyun.com/detail/342788.html?page='+page+'';}">10) ? 10 :
location='https://bbs.aliyun.com/detail/342788.html?page='+page+'';">Go
访问内容超出本站范围,不能确定是否安全
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
您目前还是游客,请
验证问题: 阿里云官网域名是什么? 正确答案:www.aliyun.com
&回复后跳转到最后一页
开发者论坛为你提供“android 环信 集成发送消息崩溃”的内容,论坛中还有更多关于
的内容供你使用,该内容是网友上传,与开发者论坛无关,如果需要删除请联系zixun-group@service.aliyun.com,工作人员会在5个工作日内回复您。

我要回帖

更多关于 安卓sdk环境变量配置 的文章

 

随机推荐