企信需要實現的功能
先梳理一下優悅家裝企信的邏輯,主要要滿足羣聊和消息推送功能。
羣聊
一個項目(Project)分爲兩個羣,一個客服羣,一個工作羣。
消息
消息分爲很多種,有工作提醒,裝修提醒,薪資提醒等等。
設計思路
和服務器商議決定,採用websocket協議,傳輸json字符串,實現消息通信。
每一種業務都對應一種業務ID,比如
public static final int HEARTBEAT_CLIENT = 1;//心跳業務ID(客戶端發送)
public static final int HEARTBEAT_SERVER = 2;//心跳業務ID(服務器返回)
public static final int USER_LOGIN = 1001; //用戶登陸業務ID
public static final int USER_LOGIN_SUCCEED = 1010;//登陸成功業務ID
public static final int USER_LOGIN_ERROR = 1020;//登陸失敗業務ID
public static final int USER_LOGIN_IN_OTHER_PLACES = 1030;//該用戶登陸在其他地方登陸
......
WebSocket實現
採用的開源的java-websocket實現,這個庫封裝好了websocket的連接,發送,接受消息的代碼,使用簡單!
簡單流程
當APP啓動時,打開websocket的連接,當用戶登陸後,綁定用戶。綁定用戶成功後,就可以正常的發送的和接送消息。
打開websocket的連接
在MyApplication.java類
QXConfig config = new QXConfig("com.keith.renovation", BuildConfig.SERVER_WS_URL);
config.setClientName("APP_B");
QXIMClient.init(this, config);
上述代碼,會啓動一個service服務,最終調用java-websocket的連接方法,打開websocket連接。
- 綁定用戶
QXIMClient.bind(token);
調用上述代碼會,發送登陸的消息給服務器,如果登陸成功,服務器會返回登陸成功的消息通知客服端,如果登陸失敗,服務器會發送登陸失敗的消息通知客戶端。
發送消息
調用QXIMClient.java的sendMessage()發送消息,會將消息轉換成json字符串,然後發送給服務器。如果發送成功,服務器會返回成功的消息通知客服端,如果發送失敗,服務器會發送登陸失敗的消息通知客戶端。
如何接受消息
先通過QXIMClient.registerMessageReceiveListener註冊listener,當有消息來之後,就可以在listener的onQXMessageReceive方法接收到,當你不需要接收消息的時候,記得unregister防止內存泄露,採用所謂的觀察者模式!
羣消息
普通文本消息(QXGroupTextMessage.java)
圖片消息(QXGroupImageMessage.java)
位置消息(QXGroupLocationMessage.java)
文檔消息(QXGroupDocumentMessage.java)
語音消息(QXGroupVoiceMessage.java)
羣成員變動消息(QXGroupMemberMessage.java)
羣消息的存儲
將消息統一存儲到sqlite3中,對應的實體類(GroupMessageEntity.java)
private int id;//主鍵ID
private String messageId;//本地生成的ID
private String sn;//服務器生成消息序列號
private int businessId;//業務ID,區分是什麼消息(文本?圖片?位置?)
private long groupId;//羣ID
private long userId;//發送者ID
private long toUserId; //消息發送給誰
private String groupType;//羣類型(客服/同事)
private String fromSource;//消息來源
private boolean cancelFlag = false;//消息是否被撤銷
private int status = STATUS_GET;//消息狀態(發送成功/發送失敗/已接受/發送中)
@Column(nullable = true)
private String content;//發送消息的json字符串,這個很重要,通過它可以轉化成消息類
private String text;//文本消息發送消息的文本內容,(這個是爲了通過關鍵字搜索內容)
private long createTime;//發送/接收時間
當發送/接受到羣消息時,將消息存儲到數據庫,具體代碼
private void processGroupMessage(QXGroupMessage groupMessage){
if(groupMessage == null){
return;
}
//通知監聽
for(OnMessageReceiveListener listener: mMessageReceiveList){
listener.onQXMessageReceive(groupMessage);
}
//保存消息到數據庫
sendQXMessageToByStoreHandler(groupMessage, WHAT_MESSAGE_RECV);
sendQXMessageReceipt(groupMessage.getMsgId());
}
由於聊天界面(如下圖所示)有顯示項目羣的最後收到的一條消息,所以還需要在項目信息(ProjectEntity.java)裏面存儲最後收到的一條羣消息。
private String messageId;
private String lastMessage;//最後收到的這條消息
private long lastMessageFromGroupId;//最後一條消息來自的羣ID
private long lastMessageTime;//最後一條消息的發送的時間
private int lastMessageStatus;//最後一條消息狀態
private int unreadWorkNum;//工作羣未讀的消息個數
private int unreadCustomerNum;//客戶羣是未讀的消息個數
private long workGroupId;//工作羣ID
private long customerGroupId;//客服羣ID
當發送或者/接收到羣消息時,就去更新項目信息中最後一條消息的相關信息,如下所示。
mMessageStoreHandler = new Handler(mHandlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
//TODO should process android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5):
if(msg.obj instanceof QXCancelMessage){
//收到撤銷消息
cancelMessage((QXCancelMessage) msg.obj, msg.what == WHAT_MESSAGE_RECV);
return;
}
if(msg.obj instanceof QXGroupMessage){
//收到羣消息
saveQXMessage((QXGroupMessage)msg.obj, msg.what == WHAT_MESSAGE_RECV);
}else if(msg.obj instanceof QXReceiptSuccessMessage){
//消息發送成功的回執消息
QXReceiptSuccessMessage messageSuccessReceipt = (QXReceiptSuccessMessage)msg.obj;
saveQXMessageSuccessReceipt(messageSuccessReceipt);
}else if(msg.obj instanceof QXReceiptErrorMessage){
//消息發送失敗的回執消息
QXReceiptErrorMessage messageSuccessReceipt = (QXReceiptErrorMessage)msg.obj;
saveQXMessageErrorReceipt(messageSuccessReceipt);
}else if(msg.obj instanceof QXProjectMessage){
//收到項目消息
modifyProjectStatus((QXProjectMessage) msg.obj);
}
}
};
消息推送部分
行政工作提醒
行政工作模塊,分爲通知、任務、日誌、審批。如果想監聽到工作消息,可以通過QXIMClient.registerOnExecutiveListener方法。
應用模塊裏面的消息
調用QXIMClient.registerOnQXWorkMessageListener方法,可以收到 實力龍發、促銷活動、問題處理、企業公告 的消息。
裝修模塊提醒
調用QXIMClient.registerOnProjectMessageListener方法,可以收到 節點驗收、客戶洽談、項目進度 的消息。
界面部分
聊天界面
聊天界面時最複雜的界面(ChatActivity),所以只針對聊天界面作一個說明
如上圖所示,界面分爲三個部分,第一部分是title,第二部分是content,由fragment構成,第三部分是鍵盤(注意,爲了方便處理,鍵盤部分在fragment中)
第一部分不多說。第二部分,是一個listView。第三部分是利用github上的一個鍵盤,具體點擊