/**
* Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fanxin.applib.controller;
import java.util.Iterator;
import java.util.List;
import com.easemob.EMCallBack;
import com.easemob.EMConnectionListener;
import com.easemob.EMError;
import com.easemob.chat.EMChat;
import com.easemob.chat.EMChatConfig.EMEnvMode;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMChatOptions;
import com.easemob.chat.OnMessageNotifyListener;
import com.easemob.chat.OnNotificationClickListener;
import com.fanxin.applib.model.DefaultHXSDKModel;
import com.fanxin.applib.model.HXSDKModel;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
/**
* The developer can derive from this class to talk with HuanXin SDK
* All the Huan Xin related initialization and global listener are implemented in this class which will
* help developer to speed up the SDK integration。
* this is a global instance class which can be obtained in any codes through getInstance()
*
* 开发人员可以选择继承这个环信SDK帮助类去加快初始化集成速度。此类会初始化环信SDK,并设置初始化参数和初始化相应的监听器
* 不过继承类需要根据要求求提供相应的函数,尤其是提供一个{@link HXSDKModel}. 所以请实现abstract protected HXSDKModel createModel();
* 全局仅有一个此类的实例存在,所以可以在任意地方通过getInstance()函数获取此全局实例
*
* @author easemob
*
*/
public abstract class HXSDKHelper {
private static final String TAG = "HXSDKHelper";
/**
* application context
*/
protected Context appContext = null;
/**
* HuanXin mode helper, which will manage the user data and user preferences
*/
protected HXSDKModel hxModel = null;
/**
* MyConnectionListener
*/
protected EMConnectionListener connectionListener = null;
/**
* HuanXin ID in cache
*/
protected String hxId = null;
/**
* password in cache
*/
protected String password = null;
/**
* init flag: test if the sdk has been inited before, we don't need to init again
*/
private boolean sdkInited = false;
/**
* the global HXSDKHelper instance
*/
private static HXSDKHelper me = null;
public HXSDKHelper(){
me = this;
}
/**
* this function will initialize the HuanXin SDK
*
* @return boolean true if caller can continue to call HuanXin related APIs after calling onInit, otherwise false.
*
* 环信初始化SDK帮助函数
* 返回true如果正确初始化,否则false,如果返回为false,请在后续的调用中不要调用任何和环信相关的代码
*
* for example:
* 例子:
*
* public class DemoHXSDKHelper extends HXSDKHelper
*
* HXHelper = new DemoHXSDKHelper();
* if(HXHelper.onInit(context)){
* // do HuanXin related work
* }
*/
public synchronized boolean onInit(Context context){
if(sdkInited){
return true;
}
appContext = context;
// create HX SDK model
hxModel = createModel();
// create a defalut HX SDK model in case subclass did not provide the model
if(hxModel == null){
hxModel = new DefaultHXSDKModel(appContext);
}
int pid = android.os.Process.myPid();
String processAppName = getAppName(pid);
Log.e("ewrwetwetwet", "process app name : " + processAppName);
// 如果app启用了远程的service,此application:onCreate会被调用2次
// 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次
// 默认的app会在以包名为默认的process name下运行,如果查到的process name不是app的process name就立即返回
if (processAppName == null || !processAppName.equalsIgnoreCase(hxModel.getAppProcessName())) {
Log.e(TAG, "enter the service process!");
// 则此application::onCreate 是被service 调用的,直接返回
return false;
}
// 初始化环信SDK,一定要先调用init()
EMChat.getInstance().init(context);
// 设置sandbox测试环境
// 建议开发者开发时设置此模式
if(hxModel.isSandboxMode()){
EMChat.getInstance().setEnv(EMEnvMode.EMSandboxMode);
}
if(hxModel.isDebugMode()){
// set debug mode in development process
EMChat.getInstance().setDebugMode(true);
}
Log.d(TAG, "initialize EMChat SDK");
initHXOptions();
initListener();
sdkInited = true;
return true;
}
/**
* get global instance
* @return
*/
public static HXSDKHelper getInstance(){
return me;
}
public HXSDKModel getModel(){
return hxModel;
}
public String getHXId(){
if(hxId == null){
hxId = hxModel.getHXId();
}
return hxId;
}
public String getPassword(){
if(password == null){
password = hxModel.getPwd();
}
return password;
}
public void setHXId(String hxId){
if (hxId != null) {
if(hxModel.saveHXId(hxId)){
this.hxId = hxId;
}
}
}
public void setPassword(String password){
if(hxModel.savePassword(password)){
this.password = password;
}
}
/**
* the subclass must override this class to provide its own model or directly use {@link DefaultHXSDKModel}
* @return
*/
abstract protected HXSDKModel createModel();
/**
* please make sure you have to get EMChatOptions by following method and set related options
* EMChatOptions options = EMChatManager.getInstance().getChatOptions();
*/
protected void initHXOptions(){
Log.d(TAG, "init HuanXin Options");
// 获取到EMChatOptions对象
EMChatOptions options = EMChatManager.getInstance().getChatOptions();
// 默认添加好友时,是不需要验证的,改成需要验证
options.setAcceptInvitationAlways(hxModel.getAcceptInvitationAlways());
// 默认环信是不维护好友关系列表的,如果app依赖环信的好友关系,把这个属性设置为true
options.setUseRoster(hxModel.getUseHXRoster());
// 设置收到消息是否有新消息通知(声音和震动提示),默认为true
options.setNotifyBySoundAndVibrate(hxModel.getSettingMsgNotification());
// 设置收到消息是否有声音提示,默认为true
options.setNoticeBySound(hxModel.getSettingMsgSound());
// 设置收到消息是否震动 默认为true
options.setNoticedByVibrate(hxModel.getSettingMsgVibrate());
// 设置语音消息播放是否设置为扬声器播放 默认为true
options.setUseSpeaker(hxModel.getSettingMsgSpeaker());
// 设置是否需要已读回执
options.setRequireAck(hxModel.getRequireReadAck());
// 设置是否需要已送达回执
options.setRequireDeliveryAck(hxModel.getRequireDeliveryAck());
// 设置notification消息点击时,跳转的intent为自定义的intent
options.setOnNotificationClickListener(getNotificationClickListener());
options.setNotifyText(getMessageNotifyListener());
}
/**
* logout HuanXin SDK
*/
public void logout(final EMCallBack callback){
EMChatManager.getInstance().logout(new EMCallBack(){
@Override
public void onSuccess() {
// TODO Auto-generated method stub
setPassword(null);
if(callback != null){
callback.onSuccess();
}
}
@Override
public void onError(int code, String message) {
// TODO Auto-generated method stub
}
@Override
public void onProgress(int progress, String status) {
// TODO Auto-generated method stub
if(callback != null){
callback.onProgress(progress, status);
}
}
});
}
/**
* 检查是否已经登录过
* @return
*/
public boolean isLogined(){
if(hxModel.getHXId() != null && hxModel.getPwd() != null){
return true;
}
return false;
}
/**
* get the message notify listener
* @return
*/
protected OnMessageNotifyListener getMessageNotifyListener(){
return null;
}
/**
*get notification click listener
*/
protected OnNotificationClickListener getNotificationClickListener(){
return null;
}
/**
* init HuanXin listeners
*/
protected void initListener(){
Log.d(TAG, "init listener");
// create the global connection listener
connectionListener = new EMConnectionListener() {
@Override
public void onDisconnected(int error) {
if (error == EMError.USER_REMOVED) {
onCurrentAccountRemoved();
}else if (error == EMError.CONNECTION_CONFLICT) {
onConnectionConflict();
}else{
onConnectionDisconnected(error);
}
}
@Override
public void onConnected() {
onConnectionConnected();
}
};
EMChatManager.getInstance().addConnectionListener(connectionListener);
}
/**
* the developer can override this function to handle connection conflict error
*/
protected void onConnectionConflict(){}
/**
* the developer can override this function to handle user is removed error
*/
protected void onCurrentAccountRemoved(){}
/**
* handle the connection connected
*/
protected void onConnectionConnected(){}
/**
* handle the connection disconnect
* @param error see {@link EMError}
*/
protected void onConnectionDisconnected(int error){}
/**
* check the application process name if process name is not qualified, then we think it is a service process and we will not init SDK
* @param pID
* @return
*/
private String getAppName(int pID) {
String processName = null;
ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
List l = am.getRunningAppProcesses();
Iterator i = l.iterator();
PackageManager pm = appContext.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;
}
}