初始化 SDK
在應(yīng)用的 Application 的 onCreate() 方法中做初始化操作,同時我們可以傳入一些設(shè)置好的 options。
@Override
public void onCreate() {
EMOptions options = initChatOptions();
//初始化
if(options == null){
EMClient.getInstance().init(this, initChatOptions());
} else{
EMClient.getInstance().init(this, options);
}
//在做打包混淆時,關(guān)閉debug模式,避免消耗不必要的資源
EMClient.getInstance().setDebugMode(true);
}
private EMOptions initChatOptions(){
EMOptions options = new EMOptions();
// 默認添加好友時,是不需要驗證的,改成需要驗證
options.setAcceptInvitationAlways(false);
// set if you need read ack
options.setRequireAck(true);
// set if you need delivery ack
options.setRequireDeliveryAck(false);
// 建議初始化SDK的時候設(shè)置成每個會話默認load一條消息,節(jié)省加載會話的時間
options.setNumberOfMessagesLoaded(1);
//you need apply & set your own id if you want to use google cloud messaging.
options.setGCMNumber("324169311137");
//you need apply & set your own id if you want to use Mi push notification
options.setMipushConfig("2882303761517426801", "5381742660801");
}
需要注意的是,如果應(yīng)用中有其它第三方的服務(wù)啟動,那么在初始化環(huán)信 SDK 之前需要添加下面相關(guān)的代碼來防止環(huán)信 SDK 被初始化 2 次。
appContext = this;
int pid = android.os.Process.myPid();
String processAppName = getAppName(pid);
// 如果APP啟用了遠程的service,此application:onCreate會被調(diào)用2次
// 為了防止環(huán)信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 調(diào)用的,直接返回
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) {
processName = info.processName;
return processName;
}
} catch (Exception e) {
// Log.d("Process", "Error>> :"+ e.toString());
}
}
return processName;
}
注冊
注冊模式分兩種,開放注冊(客戶端可以直接注冊)和授權(quán)注冊。
- 開放注冊是為了測試使用,正式環(huán)境中不推薦使用該方式注冊環(huán)信賬號;
- 授權(quán)注冊的流程是客戶端填寫好注冊信息后點擊注冊按鈕,注冊信息提交到應(yīng)用服務(wù)器,應(yīng)用服務(wù)器提供環(huán)信提供的 REST API 進行注冊,注冊完成后應(yīng)用服務(wù)器進行處理在返回給客戶端注冊結(jié)果。
登錄
調(diào)用異步方法 login() 完成登錄。需要注意的是在登錄成功后需要調(diào)用 EMClient.getInstance().chatManager().loadAllConversations(); 和 EMClient.getInstance().groupManager().loadAllGroups();這兩個方法是為了保證進入主頁后本地會話和群組都 load 完畢。
EMClient.getInstance().login(userName,password,new EMCallBack() {//回調(diào)
@Override
public void onSuccess() {
EMClient.getInstance().groupManager().loadAllGroups();
EMClient.getInstance().chatManager().loadAllConversations();
Log.d("main", "登錄聊天服務(wù)器成功!");
}
@Override
public void onProgress(int progress, String status) {
}
@Override
public void onError(int code, String message) {
Log.d("main", "登錄聊天服務(wù)器失??!");
}
});
另外如果登錄過,我們需要在應(yīng)用的歡迎界面中還要加入上面兩個方法來保證進入主頁后本地會話和群組都 load 完畢。
在 SplashActivity 類中
if(isLoggedIn()) {
EMClient.getInstance().chatManager().loadAllConversations();
EMClient.getInstance().groupManager().loadAllGroups();
...
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}
public boolean isLoggedIn() {
return EMClient.getInstance().isLoggedInBefore();
}
在我們首次登錄成功后,不需要再次調(diào)用登錄方法。在下次應(yīng)用啟動時,環(huán)信 SDK 會自動完成登錄。如果自動登錄失敗,也會讀取之前的會話信息。
自動登錄在下面幾種情況下會被取消:
- 用戶調(diào)用了 SDK 的登出動作;
- 用戶在別的設(shè)備上更改了密碼,導(dǎo)致此設(shè)備上自動登錄失?。?/li>
- 用戶的賬號被從服務(wù)器端刪除;
- 用戶從另一個設(shè)備登錄,把當(dāng)前設(shè)備上登錄的用戶踢出。
退出登錄
// 異步方法
EMClient.getInstance().logout(true, new EMCallBack() {
@Override
public void onSuccess() {
// TODO Auto-generated method stub
}
@Override
public void onProgress(int progress, String status) {
// TODO Auto-generated method stub
}
@Override
public void onError(int code, String message) {
// TODO Auto-generated method stub
}
});
有時候在執(zhí)行退出登錄時,由于網(wǎng)絡(luò)問題而導(dǎo)致賬號解綁失敗,即使界面退出,但還會收到消息的現(xiàn)象。為了避免這種情況的發(fā)生,我們可以在應(yīng)用選擇退出時彈出對話框顯示當(dāng)前網(wǎng)絡(luò)是否正常以及提示退出的風(fēng)險(繼續(xù)退出可能還會收到消息)。
需要注意的是,如果調(diào)用異步退出方法,在收到 onSuccess() 的回調(diào)后才去調(diào)用 IM 相關(guān)的方法,比如 login。
注冊連接監(jiān)聽
當(dāng)?shù)艟€時,Android SDK 會自動重連,無需進行任何操作,通過注冊連接監(jiān)聽來知道連接狀態(tài)。根據(jù) onDisconnected() 方法返回的 error 判斷賬號連接失敗的原因。
//注冊一個監(jiān)聽連接狀態(tài)的listener
EMClient.getInstance().addConnectionListener(new MyConnectionListener());
//實現(xiàn)ConnectionListener接口
private class MyConnectionListener implements EMConnectionListener {
@Override
public void onConnected() {
}
@Override
public void onDisconnected(final int error) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(error == EMError.USER_REMOVED){
// 顯示帳號已經(jīng)被移除
}else if (error == EMError.USER_LOGIN_ANOTHER_DEVICE) {
// 顯示帳號在其他設(shè)備登錄
} else {
if (NetUtils.hasNetwork(MainActivity.this))
//連接不到環(huán)信聊天服務(wù)器
else
//當(dāng)前網(wǎng)絡(luò)不可用,請檢查網(wǎng)絡(luò)設(shè)置
}
}
});
}
}
文章只是作為自己記錄學(xué)習(xí)使用,如果有使用不當(dāng)?shù)牡胤娇梢訞我,謝謝。
參考文章:環(huán)信開發(fā)文檔