前言
上次說了下簡單的框架構架,主要是解釋了下MVP的原理實現。雖然上次的功能沒有很多,但主要是把框架搭好,才能更好的進行下面的操作。如果還有不瞭解的可以先看下我前面的文章:Android高仿微信之mvp實現(一)
好了,這次我們要介紹的是微信聊天界面功能的簡單實現。
原理
其實知道了原理你就會發現它是多麼的簡單。這裏沒有服務器所以是基於推送實現的,網上也有一些這方面的資料,一般是基於百度雲的,我這裏是基於小米推送來實現消息的傳遞。大家都知道現在推送無處不在,如果還沒有接觸推送的話,還是先去簡單的補下功課在來看就能更好的瞭解下面說的。
要想實現消息的傳遞,就要有發送與接收功能,首先對於接收so easy 了只要我們在自己的Android應用中集成小米的I**SDK**(我這裏是以小米推送爲例的)。就已經實現的接收功能,對於接收我分了兩種,一種的正常聊天得信息,而另一種就是我們自己註冊時發送的信息。對於第一種消息我們要根據用戶設備唯一標識與用戶賬號來存儲下發過來的消息,爲以後顯示不同用戶聊天記錄。對於第二中,是在我們使用時必須先註冊,一旦註冊成功就會向所有的用戶發送一條註冊信息,該消息包括用戶的基本信息與設備標識,只要在信息時間的有效時間之內,註冊了得用戶就能接收該註冊消息。這個是很重要的身份識別,對消息的發送,用戶的添加都是重要的標識。說了接收,反過來發送也是一樣的分兩種,只是旋轉一下位置而已。
配置小米SDK
首先進入小米開發平臺,爲自己的應用開啓推送功能,然後下載SDK根據官方文檔做好相應的配置,前期就大功告成了。
如果沒接觸過的只要耐心看文檔就沒什麼問題,文檔很詳細
接收
前面我已經說了接收是相對來說較簡單的了,如果你前面配置好了小米的SDK,那麼你就有一個自定義的extends PushMessageReceiver的類,在該類中用各種相應的接收信息方法,對了忘了說消息的發送類型,這裏分爲兩種
- 通知欄顯示的消息
- 透傳消息
通知欄顯示的消息不用我多說了,至於透傳消息簡單點就是不用通知欄顯示,直接在內部接收發送過來的消息。
我們聊天使用的當然的透傳消息,所以我們可以在下面的方法中接收到透傳發送過來的消息對於兩種接收消息做相應的處理:
/**
* 接收服務器發送的透傳消息
*
* @param context
* @param message
*/
@Override
public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
mMessage = message.getContent();
if (!TextUtils.isEmpty(message.getTopic())) {
mTopic = message.getTopic();
} else if (!TextUtils.isEmpty(message.getAlias())) {
mAlias = message.getAlias();
}
Intent intent = new Intent();
//user information
if (mMessage.indexOf("^") != -1 && mMessage.indexOf("@") != -1) {
int index1 = mMessage.lastIndexOf("^");
int index2 = mMessage.lastIndexOf("@");
String userName = mMessage.substring(0, index1);
String regId = mMessage.substring(index1 + 1, index2);
String number = mMessage.substring(index2 + 1);
RegisterInfo info = new RegisterInfo();
info.setUserName(userName);
info.setNumber(number);
info.setRegId(regId);
RegisterDataHelper helper = new RegisterDataHelper(App.getAppContext());
Cursor cursor = helper.query(number, regId);
if (cursor != null && cursor.getCount() > 0) {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
if (CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.REGID).equals(regId)
&& CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.NUMBER).equals(number)) {
if (!CursorUtils.formatString(cursor, RegisterDataHelper.RegisterDataInfo.USER_NAME).equals(userName))
// update user information
helper.update(info, number, regId);
cursor.close();
return;
}
}
cursor.close();
}
// insert user information
helper.insert(info);
if (SPUtils.getString("regId").equals(App.DEVELOPER_ID)){
WXDataHelper wxHelper = new WXDataHelper(App.getAppContext());
WXItemInfo itemInfo = new WXItemInfo();
itemInfo.setRegId(regId);
itemInfo.setTitle(userName);
itemInfo.setNumber(number);
itemInfo.setContent(String.format(App.HELLO_MESSAGE, userName));
itemInfo.setCurrentAccount(SPUtils.getString("userPhone"));
itemInfo.setTime(CalendarUtils.getCurrentDate());
wxHelper.insert(itemInfo);
}
} else {
// chat information
int index1 = mMessage.lastIndexOf("(");
String rMessage = mMessage.substring(0, index1);
String extraMessage = mMessage.substring(index1 + 1);
int index2 = extraMessage.indexOf("@");
int index3 = extraMessage.indexOf("@", index2 + 1);
String receiverNumber = extraMessage.substring(0, index2);
String regId = extraMessage.substring(index2 + 1, index3);
String sendNumber = extraMessage.substring(index3 + 1);
ChatMessageInfo chatMessageInfo = new ChatMessageInfo();
chatMessageInfo.setMessage(rMessage);
chatMessageInfo.setFlag(0);
chatMessageInfo.setTime(CalendarUtils.getCurrentDate());
chatMessageInfo.setReceiverNumber(receiverNumber);
chatMessageInfo.setRegId(regId);
chatMessageInfo.setSendNumber(sendNumber);
if (App.mNumber.equals(sendNumber) && App.mRegId.equals(regId)) {
//在當前聊天界面
intent.setAction("com.idisfkj.hightcopywx.chat");
Bundle bundle = new Bundle();
bundle.putSerializable("chatMessageInfo", chatMessageInfo);
intent.putExtras(bundle);
App.getAppContext().sendBroadcast(intent);
} else {
//不在當前聊天界面
ChatMessageDataHelper helper = new ChatMessageDataHelper(App.getAppContext());
helper.insert(chatMessageInfo);
}
}
}
代碼就不解釋了,自己研究研究
發送
如果你看了文檔的話就應該有點頭緒了,發送就是使用HTTP請求向小米所提供的API根據你提供的regId、userAccount、alias、topic等發送你要發送的消息內容,我用的是regId API:https://api.xmpush.xiaomi.com/v2/message/regid
下面是發送代碼:
@Override
public void requestData(final requestListener listener, final String chatContent, final String number, final String regId, final ChatMessageDataHelper helper) {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, UrlUtils.ChatUrl(chatContent, number, regId)
, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject jsonObject) {
mChatMessageInfo = new ChatMessageInfo();
mChatMessageInfo.setMessage(chatContent);
mChatMessageInfo.setFlag(1);
mChatMessageInfo.setTime(CalendarUtils.getCurrentDate());
mChatMessageInfo.setReceiverNumber(number);
mChatMessageInfo.setRegId(regId);
mChatMessageInfo.setSendNumber(SPUtils.getString("userPhone", ""));
listener.onSucceed(mChatMessageInfo, helper);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Log.d("TAG", volleyError.getMessage());
listener.onError(volleyError.getMessage());
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> header = new HashMap<>();
header.put("Authorization", "key=" + App.APP_SECRET_KEY);
return header;
}
};
VolleyUtils.addQueue(jsonObjectRequest, "chatRequest");
}
由於涉及的代碼還是有點多的,這裏就不一一展開,有興趣的可以自己根據後面的地址Star、Fork下載代碼查看。
如果你安裝註冊了,由於時間原因,目前聊天界面只會自動添加我爲好友,你們如果有不懂得可以簡單的發消息給我,但不一定都會回。好了,下面看看效果吧