這兩天除錯環信的心得
一.整合就不多說了,官方文件都有的,可以自己去看:
整合進來有一個小的問題就是設定暱稱和頭像。
1、在登入的時候,把自己登入成功時後臺返回的資訊儲存到sharedpreferences中,需要包含需要的頭像和暱稱。
new Thread(new Runnable() {
@Override
public void run() {
EMClient.getInstance().login(username, password, new EMCallBack() {
@Override
public void onSuccess() {
// 登陸成功,儲存使用者暱稱與頭像URL
AppSPUtils.setValueToPrefrences("name", loginBean.getName());
AppSPUtils.setValueToPrefrences("logoUrl", loginBean.getLogoUrl());
// 將自己伺服器返回的環信賬號、暱稱和頭像URL設定到幫助類中。
DemoHelper.getInstance().getUserProfileManager().updateCurrentUserNickName(loginBean.getName() );
DemoHelper.getInstance().getUserProfileManager().setCurrentUserAvatar(loginBean.getLogoUrl());
DemoHelper.getInstance().setCurrentUserName(loginUser.getHxId()); // 環信Id
// ------以下參考demo中的,載入群組和載入訊息。然後跳轉到首頁-------
2、AppSPUtils是個人寫的一個工具類,大家可以自己寫一個,給出參考程式碼。
public class AppSPUtils {
private final static int MODE_SPEC = android.os.Build.VERSION.SDK_INT <= 10 ? 0 : Context.MODE_MULTI_PROCESS;
public static SharedPreferences getSharedPreferences(String name) {
return MainApplication.getContext().getSharedPreferences(name,
Context.MODE_PRIVATE | MODE_SPEC);
}
public static SharedPreferences getAppSharedPreferences() {
return getSharedPreferences(Constants.SP_APP);
}
public static String getValueFromPrefrences(String key, String defaultValue) {
return getValueFromPrefrences(getAppSharedPreferences(), key, defaultValue);
}
public static void setValueToPrefrences(String key, String value) {
try {
SharedPreferences preferences = getAppSharedPreferences();
if (null != preferences) {
preferences.edit().putString(key, value).commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 退出登入時要呼叫
public static void clean() {
try {
SharedPreferences preferences = getAppSharedPreferences();
if (null != getAppSharedPreferences()) {
getAppSharedPreferences().edit().clear().commit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、儲存好自己的資訊後,已經成功了四分之一,現在是如何將自己的頭像暱稱等資訊傳送出去,最簡單的就是使用擴充套件訊息了,在ChatActivity中可以看到,基本上只做了一件事,保證只有一個ChatActivity,那我們的程式碼在哪裡?就在ChatFragment裡面。找到程式碼,可以看到其實它是繼承自EaseChatFragment,很多內容在easeui中已經做好了。這時你會發現ChatFragment類中有一個擴充套件屬性的說明,沒錯,就是這個方法,把你要傳送的內容盡情的傳送吧,現附上傳送頭像和暱稱的程式碼:
@Override
public void onSetMessageAttributes(EMMessage message) {
if (isRobot) {
// 設定訊息擴充套件屬性
message.setAttribute("em_robot_message", isRobot);
}
// 通過擴充套件屬性,將userPic和userName傳送出去。
String userPic = AppSPUtils.getValueFromPrefrences("logoUrl", "");
if (!TextUtils.isEmpty(userPic)) {
message.setAttribute("userPic", userPic);
}
String userName = AppSPUtils.getValueFromPrefrences("name", "");
if (!TextUtils.isEmpty(userName)) {
message.setAttribute("userName", userName);
}
}
4、傳送完成,你已經完成了四分之二的任務了。傳送完成後,肯定需要一個接收,其實demo中的廣播已經接收好了,那麼我們跟隨著廣播的腳步,來到DemoHelper這個類,初次看這個類,都是雲一樣的感覺,經過一番查詢,發現有個onMessageReceived的方法,並且還有註釋“全域性監聽”,趕緊開工,試試接收吧,可以自己打一下log出來看是不是拿到了我們要的。並且照著demoHelper中的儲存方法,將接收到的內容儲存起來。
@Override
public void onMessageReceived(List<EMMessage> messages) {
for (EMMessage message : messages) {
message.setMsgTime(System.currentTimeMillis());
//************接收並處理擴充套件訊息***********************
String userName = message.getStringAttribute("userName", "");
String userPic = message.getStringAttribute("userPic", "");
String hxIdFrom = message.getFrom();
EaseUser easeUser = new EaseUser(hxIdFrom);
easeUser.setAvatar(userPic);
easeUser.setNick(userName);
// 存入記憶體
getContactList();
contactList.put(hxIdFrom, easeUser);
// 存入db
UserDao dao = new UserDao(MainApplication.getContext());
List<EaseUser> users = new ArrayList<EaseUser>();
users.add(easeUser);
dao.saveContactList(users);
getModel().setContactSynced(true);
// 通知listeners聯絡人同步完畢
notifyContactsSyncListener(true);
if (isGroupsSyncedWithServer()) {
notifyForRecevingEvents();
}
// ******************擴充套件資訊處理完成**********************
EMLog.d(TAG, "onMessageReceived id : " + message.getMsgId());
// 應用在後臺,不需要重新整理UI,通知欄提示新訊息
if (!easeUI.hasForegroundActivies()) {
getNotifier().onNewMsg(message);
}
}
}
5、資訊都收到了,就差最後一步就可以顯示了,不知道你們是不是激動,反正我是激動了。那在哪裡進行顯示呢?還是在DemoHelper中,找到getUserInfo方法,程式碼如下:private EaseUser getUserInfo(String hxId) {// 獲取user資訊,demo是從記憶體的好友列表裡獲取,// 實際開發中,可能還需要從伺服器獲取使用者資訊,// 從伺服器獲取的資料,最好快取起來,避免頻繁的網路請求
private EaseUser getUserInfo(String hxId) {
// 獲取user資訊,demo是從記憶體的好友列表裡獲取,
// 實際開發中,可能還需要從伺服器獲取使用者資訊,
// 從伺服器獲取的資料,最好快取起來,避免頻繁的網路請求
if (hxId.equals(EMClient.getInstance().getCurrentUser())) {
EaseUser currentUserInfo = getUserProfileManager().getCurrentUserInfo();
return currentUserInfo;
}
EaseUser easeUser;
if (contactList != null && contactList.containsKey(hxId)) {
} else { // 如果記憶體中沒有,則將本地資料庫中的取出到記憶體中。
getContactList();
}
// // TODO 獲取不在好友列表裡的群成員具體資訊,即陌生人資訊,demo未實現
// if (user == null && getRobotList() != null) {
// user = getRobotList().get(hxId);
// }
easeUser = contactList.get(hxId);
if(easeUser == null){
easeUser = new EaseUser(hxId);
} else {
if(TextUtils.isEmpty(easeUser.getNick())){ // 如果名字為空,則顯示環訊號碼
easeUser.setNick(easeUser.getUsername());
}
}
return easeUser;
}
OK,大功告成,到這裡你的頭像已經可以顯示了。。恭喜你!有朋友還有疑問,為什麼頭像是方形的,要變成圓形怎麼辦?指個路,在easeui中的utils包下,找到EaseUserUtils,這裡就是顯示使用者頭像和使用者暱稱的地方,通過Glide可以輕鬆顯示圓形頭像,百度有很多方法,這裡就不多講了,同樣,你也可以通過其他圖形載入框架來完成。很多朋友不明白擴充套件訊息的是什麼東西,也不明白為什麼照著程式碼敲就能夠完成頭像的顯示,那下面就給大家粗淺的講講所涉及到的邏輯關係。擴充套件訊息:就是你每一次傳送訊息,都會附帶在你傳送內容上面的額外訊息,他會隨著你的內容傳送出去,每次會多一點點流量,但微乎其微,個人認為並無多大影響。顯示頭像邏輯:區分為本地化快取和執行記憶體快取,在demoHelper中可以發現,有一個成員變數private Map contactList; 這個就是用來儲存在執行記憶體快取的,只有通過執行快取,顯示頭像是最順暢的,如果每次都從資料庫中讀取的話,聊天介面會比較卡,有朋友儲存在SP裡面,以ID做為KEY,頭像和暱稱等拼接做為value進行快取,取出後再拆分開分別取值,據說是不卡,大家可以試一下。本地化儲存是為了在每次開啟軟體的時候,從本地儲存中拿到執行記憶體中使用做準備,大家可以認真看看demoHelper和MainActivity中的程式碼。———————————————————————————-講了方法2設定頭像,那麼方法1,個人不推薦,但這裡給出處理的過程,如有個別有需求的,可以按方法1來處理:1、登入成功後,在手機子執行緒,訪問你們的後臺伺服器,拿到所有好友的環信ID,頭像,暱稱。然後按上面的儲存方法,儲存到本地中,完成後傳送廣播或EventBus之類到,重新整理訊息介面和ChatFragment。2、在getUserInfo中,寫和上面擴充套件訊息一樣的內容,將如果執行快取和本地都拿不到,則發起網路請求到後臺獲取頭像,等請求到內容後,再發出廣播或EventBus通知重新整理訊息介面和ChatFragment。————————————————————————————-以上僅為本人在開發過程中的一點小小心得,demo中的儲存運存和本地儲存的方法,大家也可以單獨寫,並不會影響程式的執行
監聽傳送過來的訊息的程式碼 在主頁面中實現:
EMMessageListener messageListener = new EMMessageListener() {
@Override
public void onMessageReceived(List<EMMessage> messages) {
// 提示新訊息
for (EMMessage message : messages) {
DemoHelper.getInstance().getNotifier().onNewMsg(message);
}
refreshUIWithMessage();
}
@Override
public void onCmdMessageReceived(List<EMMessage> messages) {
}
@Override
public void onMessageReadAckReceived(List<EMMessage> messages) {
}
@Override
public void onMessageDeliveryAckReceived(List<EMMessage> message) {
}
@Override
public void onMessageChanged(EMMessage message, Object change) {
}
};
private void refreshUIWithMessage() {
runOnUiThread(new Runnable() {
public void run() {
// 重新整理bottom bar訊息未讀數
// 當前頁面如果為聊天曆史頁面,重新整理此頁面
if (conversationListFragment != null) {
conversationListFragment.refresh();
}
}
});
}
在主頁面中實現:
@Override
protected void onResume() {
super.onResume();
EMClient.getInstance().chatManager().addMessageListener(messageListener);
}
@Override
protected void onStop() {
EMClient.getInstance().chatManager().removeMessageListener(messageListener);
super.onStop();
}