常见错误


Q:环信的 AppKey 可以写到代码里面吗?

A:不可以,必须写在 AndroidManifest.xml 中,因为在 SDK 中取 AppKey 是指定到 AndroidManifest.xml 的。

Q:SDK 的初始化可以不写在 application 里面吗?

A:不允许,要写在 application 的 oncreate 方法里面,以保证初始化成功。(写在其他地方可能会造成自踢现象)

Q:自踢现象是什么?什么情况下会有?

A:自踢现象的产生为多次调用环信的初始化方法,可以通过环信 log 内搜索 ‘conflict’ 关键字,如果存在且没有在其他手机登录,则认为是自踢现象。

环信在手机端是单点登录的(也就是说同时只能在一台设备(手机)登录),需要添加在其他地方登录的监听,如果在其他地方登录,log 日志中即有 conflict 关键字。

严重的后果是:自己刚登录后就会收到被踢的回调。因此要多加注意此问题。

怎样避免:正确按照环信 demo 或者文档所写,在 application 中初始化,添加第三方服务启动 application 的检测。上线前测试和查看日志。

通过 adb 获取环信 log 的方法:

adb pull /sdcard/Android/data/your packagename/your appkey/log

your packagename:为你APP的包名,your appkey:为你在环信申请的 AppKey

Q:SDK 默认是自动登录,我想手动登录,可以取消吗?

A:可以,只要调用 EMChat.getInstance().setAutoLogin(false) 放在 SDK 初始化的前边就行。

注:如果要实现每次手动登录,一定要关掉自动登录。

带conflict标志的日志

如果有这种 conflict 标志的日志出现那就是被踢了。

  1. 确认一下是否在 application 里面加了下面那个判断;
  2. 确认是否在成功登录以后调了创建用户的方法(不允许在登录以后还去调创建账户的方法)。

判断异常

上图报的错多数情况因为判断没有加,参照 Demo 的 application 里面把下面这段代码加上:

appContext = this;
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("com.easemob.chatuidemo")) {
    Log.e(TAG, "enter the service process!");
    //"com.easemob.chatuidemo"为Demo的包名,换到自己项目中要改成自己包名
    
    // 则此application::onCreate 是被service调用的,直接返回
    return;
}

private String getAppName(int pID) {
	String processName = null;
	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());
		try {
			if (info.pid == pID) {
				CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
				// Log.d("Process", "Id: "+ info.pid +" ProcessName: "+
				// info.processName +"  Label: "+c.toString());
				// processName = c.toString();
				processName = info.processName;
				return processName;
			}
		} catch (Exception e) {
			// Log.d("Process", "Error>> :"+ e.toString());
		}
	}
	return processName;
}

未登录情况下群组是获取不到的,本地数据库中如果没有存储群组列表会从服务器获取,就调 EMGroupManager.getInstance().getGroupsFromServer(),如果本地已经存储了群组列表就要先调 EMGroupManager.getInstance().loadAllGroups() 从本地 db 获取群组放到内存中,在内存中获取群组列表调 EMGroupManager.getInstance().getAllGroups()

Q:屏蔽群组出现 forbidden(403) Owner privileges required 是什么原因?

A:检查你是否已经对该群组做了屏蔽,再次调用屏蔽的方法则会返回上述问题。

未登录情况下聊天记录是获取不到的,登录后先调用 EMChatManager.getInstance().loadAllConversations() 放到内存中,从内存中在调用 EMChatManager.getInstance().getAllConversations() 去获取所有会话,获取单个会话 EMChatManager.getInstance().getConversation(username)。

注册用户失败错误

createAccountOnServer 这个是注册用户的方法,如果出现了 not-allowed(405) 错误,那就让他去 http://console.easemob.com/ 找,把那个用户注册模式切换成开放模式,如下图:

切换为开放注册模式

Q:注册了接收透传消息的广播,对方发送透传消息成功了,为什么收不到透传消息?

A:检查一下是否在注册完广播以后加上 EMChat.getInstance().setAppInited()

如果 apk 要打包混淆的话,debug 模式要关闭,否则会报错。


上一页:EaseUI使用指南

下一页:Android SDK API Doc