package com.arrownock.opensource.arrownockers.utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import com.arrownock.opensource.arrownockers.chat.ChatActivity;
import com.arrownock.opensource.arrownockers.chat.SessionActivity;
import com.arrownock.opensource.arrownockers.topic.Message;
import com.arrownock.opensource.arrownockers.topic.MessageEntity.EntityType;
import com.arrownock.opensource.arrownockers.topic.MessageListActivity;
import com.arrownock.opensource.arrownockers.topic.TopicListActivity;
import com.arrownock.opensource.arrownockers.utils.DBManager.Chat;
import com.arrownock.exception.ArrownockException;
import com.arrownock.im.AnIM;
import com.arrownock.im.AnIMMessage;
import com.arrownock.im.AnIMMessageType;
import com.arrownock.im.AnIMStatus;
import com.arrownock.im.AnPushType;
import com.arrownock.im.callback.AnIMAddClientsCallbackData;
import com.arrownock.im.callback.AnIMBinaryCallbackData;
import com.arrownock.im.callback.AnIMBindAnPushServiceCallbackData;
import com.arrownock.im.callback.AnIMCreateTopicCallbackData;
import com.arrownock.im.callback.AnIMGetClientIdCallbackData;
import com.arrownock.im.callback.AnIMGetClientsStatusCallbackData;
import com.arrownock.im.callback.AnIMGetSessionInfoCallbackData;
import com.arrownock.im.callback.AnIMGetTopicInfoCallbackData;
import com.arrownock.im.callback.AnIMGetTopicListCallbackData;
import com.arrownock.im.callback.AnIMMessageCallbackData;
import com.arrownock.im.callback.AnIMMessageSentCallbackData;
import com.arrownock.im.callback.AnIMNoticeCallbackData;
import com.arrownock.im.callback.AnIMReadACKCallbackData;
import com.arrownock.im.callback.AnIMReceiveACKCallbackData;
import com.arrownock.im.callback.AnIMRemoveClientsCallbackData;
import com.arrownock.im.callback.AnIMStatusUpdateCallbackData;
import com.arrownock.im.callback.AnIMTopicBinaryCallbackData;
import com.arrownock.im.callback.AnIMTopicMessageCallbackData;
import com.arrownock.im.callback.AnIMUnbindAnPushServiceCallbackData;
import com.arrownock.im.callback.AnIMUpdateTopicCallbackData;
import com.arrownock.im.callback.IAnIMCallback;
import com.arrownock.im.callback.IAnIMHistoryCallback;
import com.arrownock.mrm.MRMJSONResponseHandler;
public class AnIMWrapper implements IAnIMCallback {
private static final String logTag = "AnIMWrapper";
private static AnIMWrapper wrapper;
private AnIM anIM;
private Map<String, Message> tmpMessages = new HashMap<String, Message>();
private static AnIMWrapperCallback delegate;
public static MessageListActivity messageListActivity;
public static TopicListActivity topicListActivity;
public static ChatActivity chatActivity;
public static SessionActivity sessionActivity;
public static boolean status = false;
private boolean willDisconnect = false;
static int retryCount = 1;
private boolean willCheckIfMyTopic = false;
public static String thisAnId;
private static Context thisContext;
// FIXME 以下注释代码用于监听网络连接状态的改变,从而执行重新连接服务器的操作
// private static NetworkChangeMonitor monitor = null;
// private class NetworkChangeMonitor extends BroadcastReceiver {
//
// @Override
// public void onReceive(Context context, Intent intent) {
// String action = intent.getAction();
// if (TextUtils
// .equals(action, "android.net.conn.CONNECTIVITY_CHANGE")) {
// if (ATUtils.getCurrentUsername() != null) {
// getWrapper().getClientId(ATUtils.getCurrentUsername());
// }
// }
// }
// }
// public void unregisterMonitor() {
// try {
// thisContext.unregisterReceiver(monitor);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// private void registerDataTransReceiver() {
// try {
// IntentFilter filter = new IntentFilter();
// filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
// filter.setPriority(1000);
//
// unregisterMonitor();
// monitor = new NetworkChangeMonitor();
// thisContext.registerReceiver(monitor, filter);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// 获取当前网络状态
private NetworkInfo getActiveNetwork(Context context) {
if (context == null)
return null;
ConnectivityManager mConnMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (mConnMgr == null)
return null;
NetworkInfo aActiveInfo = mConnMgr.getActiveNetworkInfo();
return aActiveInfo;
}
public static void init(Context context, String appKey) {
try {
if (wrapper == null) {
wrapper = new AnIMWrapper();
wrapper.anIM = new AnIM(context, appKey);
wrapper.anIM.setSecureConnection(true);
wrapper.anIM.setCallback(wrapper);
thisContext = context;
}
// FIXME 注册网络状态监听
// wrapper.registerDataTransReceiver();
} catch (ArrownockException e) {
e.printStackTrace();
}
}
public static AnIMWrapper getWrapper() {
if (wrapper == null) {
init(thisContext, AnUtils.AppKey);
}
return wrapper;
}
public void getClientId(String userId) {
Log.i(logTag, "getClientId: " + userId);
try {
wrapper.anIM.getClientId(userId);
} catch (ArrownockException e) {
e.printStackTrace();
}
}
public void getTopics(AnIMWrapperCallback callback) {
Log.i(logTag, "getTopics");
if (callback != null) {
delegate = callback;
}
try {
wrapper.anIM.getTopicList();
} catch (Exception e) {
e.printStackTrace();
}
}
public void willJoinTopic(String topicId) {
Log.i(logTag, "will join topic: " + topicId);
try {
Set<String> clientIds = new HashSet<String>();
clientIds.add(AnUtils.getCurrentClientId());
wrapper.anIM.addClientsToTopic(topicId, clientIds);
} catch (Exception e) {
e.printStackTrace();
}
}
public void willQuitTopic(String topicId) {
Log.i(logTag, "will quit topic: " + topicId);
try {
Set<String> clientIds = new HashSet<String>();
clientIds.add(AnUtils.getCurrentClientId());
wrapper.anIM.removeClientsFromTopic(topicId, clientIds);
} catch (Exception e) {
e.printStackTrace();
}
}
// 查询群组信息,获取群组内用户的clientId列表
public void willCheckIfMyTopic(String topicId) {
Log.i(logTag, "will get topicInfo: " + topicId);
willCheckIfMyTopic = true;
try {
wrapper.anIM.getTopicInfo(topicId);
} catch (Exception e) {
e.printStackTrace();
}
}
// 验证是否处于该群组
private void verifyIfMyTopic(Set<String> clientIds) {
Log.i(logTag, "will verify if my topic");
if (willCheckIfMyTopic) {
if (messageListActivity != null) {
if (clientIds == null) {
messageListActivity.onCheckIfMyTopic(false, true);
} else {
if (clientIds.contains(AnUtils.getCurrentClientId())) {
messageListActivity.onCheckIfMyTopic(true, false);
} else {
messageListActivity.onCheckIfMyTopic(false, false);
}
}
}
willCheckIfMyTopic = false;
}
}
public void connect(String clientId) {
Log.i(logTag, "connect clientId: " + clientId);
willDisconnect = false;
try {
wrapper.anIM.connect(clientId);
} catch (Exception e) {
e.printStackTrace();
}
}
public void disconnect() {
Log.i(logTag, "\t" + "disconnect");
willDisconnect = true;
try {
wrapper.anIM.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public void connectIfOffline() {
if (status == false && AnUtils.getCurrentUsername() != null) {
try {
wrapper.anIM.getClientId(AnUtils.getCurrentUsername());
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 绑定Push服务
public void bindPush(String anid) {
thisAnId = anid;
try {
wrapper.anIM.bindAnPushService(anid, AnUtils.AppKey,
AnPushType.AnPushTypeAndroid);
} catch (Exception e) {
e.printStackTrace();
}
}
public void getOfflineMessages() {
Log.i(logTag, "Fetching offline messages...");
wrapper.anIM.getOfflineHistory(AnUtils.getCurrentClientId(), 10, new IAnIMHistoryCallback() {
@Override
public void onError(ArrownockException e) {
Log.e(logTag, "Failed to fetch offline messages. " + e.getMessage());
}
@Override
public void onSuccess(List messages, int count) {
for(int i = 0; i< messages.size(); i++) {
AnIMMessage message = (AnIMMessage)messages.get(i);
if(message != null) {
if(AnIMMessageType.AnIMTextMessage == message.getType()) {
Map<String, String> customData = message.getCustomData();
String username = customData.get("username");
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Chat chat = new Chat();
chat.type = "text";
chat.fromClientId = message.getFrom();
List<String> p = new ArrayList<String>();
p.add(AnUtils.getCurrentClientId());
p.add(message.getFrom());
Collections.sort(p);
chat.parties = StringUtils.join(p, ",");
chat.message = message.getMessage();
chat.messageId = message.getMsgId();
chat.status = "unread";
chat.income = true;
chat.time = AnUtils.getTimeString(time);
chat.realname = username;
saveReceivedMessage(chat, p);
} else if(AnIMMessageType.AnIMBinaryMessage == message.getType()) {
Map<String, String> customData = message.getCustomData();
String username = customData.get("username");
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Chat chat = new Chat();
chat.type = message.getFileType();
chat.fromClientId = message.getFrom();
List<String> p = new ArrayList<String>();
p.add(AnUtils.getCurrentClientId());
p.add(message.getFrom());
Collections.sort(p);
chat.parties = StringUtils.join(p, ",");
chat.messageId = message.getMsgId();
chat.status = "unread";
chat.income = true;
chat.time = AnUtils.getTimeString(time);
chat.realname = username;
if (chat.type.equals("location")) {
chat.latitude = Double.valueOf(customData.get("latitude")
.toString());
chat.longitude = Double.valueOf(customData.get("longitude")
.toString());
} else {
chat.binary = message.getContent();
}
saveRecievedBinaryMessage(chat, p);
}
}
}
// if there is still message left, fetch them
if(count > 0) {
getOfflineMessages();
}
}
});
}
public void getTopicOfflineMessages() {
Log.i(logTag, "Fetching topic offline messages....");
wrapper.anIM.getOfflineTopicHistory(AnUtils.getCurrentClientId(), 10, new IAnIMHistoryCallback() {
public void onError(ArrownockException e) {
Log.e(logTag, "Failed to fetch topic offline messages. " + e.getMessage());
}
@Override
public void onSuccess(List messages, int count) {
for(int i = 0; i< messages.size(); i++) {
AnIMMessage message = (AnIMMessage)messages.get(i);
if(message != null) {
if(AnIMMessageType.AnIMTextMessage == message.getType()) {
String messageId = message.getMsgId();
String content = message.getMessage();
String topicId = message.getTopicId();
Map<String, String> customData = message.getCustomData();
String realname = customData.get("realname");
String username = customData.get("username");
if (realname == null) {
realname = username;
}
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Message msg = new Message();
msg.messageId = messageId;
msg.content = content;
msg.topicId = topicId;
msg.realname = realname;
msg.username = username;
msg.timestamp = time;
msg.isUnread = true;
msg.isIncoming = true;
msg.isUnsent = false;
msg.isError = false;
msg.type = EntityType.ET_TEXT;
DBManager.writeMessage(msg);
if (messageListActivity != null) {
messageListActivity.onMessage(msg);
}
if (topicListActivity != null) {
topicListActivity.onMessage(msg);
}
} else if(AnIMMessageType.AnIMBinaryMessage == message.getType()) {
String messageId = message.getMsgId();
byte[] contentData = message.getContent();
String fileType = message.getFileType();
String topicId = message.getTopicId();
Map<String, String> customData = message.getCustomData();
String realname = customData.get("realname");
String username = customData.get("username");
if (realname == null) {
realname = username;
}
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Message msg = new Message();
msg.messageId = messageId;
msg.topicId = topicId;
msg.realname = realname;
msg.username = username;
msg.timestamp = time;
msg.isUnread = true;
msg.isIncoming = true;
msg.isUnsent = false;
msg.isError = false;
if (fileType.equals("image")) {
msg.imageData = contentData;
msg.type = EntityType.ET_IMAGE;
} else if (fileType.equals("audio")) {
msg.audioData = contentData;
msg.type = EntityType.ET_AUDIO;
}
DBManager.writeMessage(msg);
if (messageListActivity != null) {
messageListActivity.onMessage(msg);
}
if (topicListActivity != null) {
topicListActivity.onMessage(msg);
}
}
}
}
// if there is still message left, fetch them
if(count > 0) {
getTopicOfflineMessages();
}
}
});
}
public String sendMessageToClients(String message, List<String> clientIds) {
String messageId = null;
try {
Set<String> clientIdSet = new HashSet<String>(clientIds);
List<String> clientIdList = new ArrayList<String>(clientIds);
Map<String, String> customData = new HashMap<String, String>();
customData.put("username", AnUtils.getCurrentUsername());
customData.put("time",
String.format("%f", new Date().getTime() / 1000.0));
messageId = wrapper.anIM.sendMessage(clientIdSet, message,
customData, true);
Chat chat = new Chat();
chat.type = "text";
chat.fromClientId = AnUtils.getCurrentClientId();
clientIdList.add(AnUtils.getCurrentClientId());
Collections.sort(clientIdList);
chat.parties = StringUtils.join(clientIdList, ",");
chat.message = message;
chat.messageId = messageId;
chat.status = "sending";
chat.income = false;
chat.time = AnUtils.getTimeString(new Date());
DBManager.addChat(chat);
} catch (ArrownockException e) {
Log.e("sendMessageToClients: ", e.getMessage());
}
return messageId;
}
public String sendBinaryToClients(byte[] binary, String fileType,
List<String> clientIds) {
String messageId = null;
try {
Set<String> clientIdSet = new HashSet<String>(clientIds);
List<String> clientIdList = new ArrayList<String>(clientIds);
Map<String, String> customData = new HashMap<String, String>();
customData.put("username", AnUtils.getCurrentUsername());
customData.put("time",
String.format("%f", new Date().getTime() / 1000.0));
messageId = wrapper.anIM.sendBinary(clientIdSet, binary, fileType,
customData, true);
Chat chat = new Chat();
chat.type = fileType;
chat.fromClientId = AnUtils.getCurrentClientId();
clientIdList.add(AnUtils.getCurrentClientId());
Collections.sort(clientIdList);
chat.parties = StringUtils.join(clientIdList, ",");
chat.binary = binary;
chat.messageId = messageId;
chat.status = "sending";
chat.income = false;
chat.time = AnUtils.getTimeString(new Date());
DBManager.addChat(chat);
} catch (ArrownockException e) {
Log.e("sendBinaryToClient: ", e.getMessage());
}
return messageId;
}
public String sendLocationToClients(double latitude, double longitude,
List<String> clientIds) {
Set<String> clientIdSet = new HashSet<String>(clientIds);
List<String> clientIdList = new ArrayList<String>(clientIds);
String messageId = null;
Map<String, String> locMap = new HashMap<String, String>();
locMap.put("latitude", String.valueOf(latitude));
locMap.put("longitude", String.valueOf(longitude));
locMap.put("username", AnUtils.getCurrentUsername());
locMap.put("time", String.format("%f", new Date().getTime() / 1000.0));
try {
messageId = wrapper.anIM.sendBinary(clientIdSet,
"Location".getBytes(), "location", locMap, true);
Chat chat = new Chat();
chat.type = "location";
chat.fromClientId = AnUtils.getCurrentClientId();
clientIdList.add(AnUtils.getCurrentClientId());
Collections.sort(clientIdList);
chat.parties = StringUtils.join(clientIdList, ",");
chat.binary = null;
chat.message = "Location...";
chat.latitude = latitude;
chat.longitude = longitude;
chat.messageId = messageId;
chat.status = "sending";
chat.income = false;
chat.time = AnUtils.getTimeString(new Date());
DBManager.addChat(chat);
} catch (ArrownockException e) {
Log.e("sendBinaryToClient: ", e.getMessage());
}
return messageId;
}
// 发送已读回执
public String sendReadACKToClients(List<String> clientIds, String messageId) {
String returnedMessageId = null;
try {
Set<String> clientIdSet = new HashSet<String>(clientIds);
returnedMessageId = wrapper.anIM
.sendReadACK(clientIdSet, messageId);
} catch (ArrownockException e) {
Log.e("sendReadACK: ", e.getMessage());
}
return returnedMessageId;
}
// 用户群组聊天发送消息
public String sendText(Message message) {
String messageId = null;
String topicId = message.topicId;
String content = message.content;
Map<String, String> customData = new HashMap<String, String>();
customData.put("realname", message.realname);
customData.put("username", message.username);
customData.put("time",
String.format("%f", message.timestamp.getTime() / 1000.0));
try {
messageId = wrapper.anIM.sendMessageToTopic(topicId, content,
customData, false);
} catch (ArrownockException e) {
e.printStackTrace();
}
if (messageId != null) {
message.messageId = messageId;
message.isIncoming = false;
message.isUnread = true;
message.isUnsent = true;
tmpMessages.put(messageId, message);
}
return messageId;
}
// 用户群组聊天发送图片
public String sendImage(Message message) {
String messageId = null;
String topicId = message.topicId;
byte[] imageData = message.imageData;
Map<String, String> customData = new HashMap<String, String>();
customData.put("realname", message.realname);
customData.put("username", message.username);
customData.put("time",
String.format("%f", message.timestamp.getTime() / 1000.0));
try {
messageId = wrapper.anIM.sendBinaryToTopic(topicId, imageData,
"image", customData, false);
} catch (ArrownockException e) {
e.printStackTrace();
}
if (messageId != null) {
message.messageId = messageId;
message.isIncoming = false;
message.isUnread = true;
message.isUnsent = true;
tmpMessages.put(messageId, message);
}
return messageId;
}
// 用户群组聊天发送声音
public String sendAudio(Message message) {
String messageId = null;
String topicId = message.topicId;
byte[] audioData = message.audioData;
Map<String, String> customData = new HashMap<String, String>();
customData.put("realname", message.realname);
customData.put("username", message.username);
customData.put("time",
String.format("%f", message.timestamp.getTime() / 1000.0));
try {
messageId = wrapper.anIM.sendBinaryToTopic(topicId, audioData,
"audio", customData, false);
} catch (ArrownockException e) {
e.printStackTrace();
}
if (messageId != null) {
message.messageId = messageId;
message.isIncoming = false;
message.isUnread = true;
message.isUnsent = true;
tmpMessages.put(messageId, message);
}
return messageId;
}
// 回调函数。添加clientId到某一个群组的回调函数
@Override
public void addClientsToTopic(AnIMAddClientsCallbackData arg0) {
if (messageListActivity != null) {
if (arg0.getException() != null) {
messageListActivity.onJoinTopic(false);
} else {
messageListActivity.onJoinTopic(true);
}
}
}
// 回调函数。绑定Push服务的回调函数
@Override
public void bindAnPushService(AnIMBindAnPushServiceCallbackData arg0) {
Log.i(logTag, "anPush bound"
+ (arg0.isError() ? arg0.getException().getErrorCode() : ""));
if (!arg0.isError()) {
AnUtils.setAnId(thisAnId);
}
}
@Override
public void createTopic(AnIMCreateTopicCallbackData arg0) {
}
// 回调函数。获取某一个userId所对应的clientId的回调函数
@Override
public void getClientId(AnIMGetClientIdCallbackData arg0) {
if (!arg0.isError()) {
Log.i(logTag, "clientId retrived: " + arg0.getClientId());
final String clientId = arg0.getClientId();
if (AnUtils.getCurrentClientId() == null) {
JSONObject params = new JSONObject();
JSONObject customFields = new JSONObject();
try {
customFields.put("clientId", clientId);
params.put("customFields", customFields);
if (AnUtils.getCurrentUserId() != null) {
params.put("id", AnUtils.getCurrentUserId());
}
MRMWrapper.getMRM(thisContext).sendPostRequest(thisContext,
"users/update", params,
new MRMJSONResponseHandler() {
@Override
public void onFailure(Throwable e,
JSONObject response) {
}
@Override
public void onSuccess(int statusCode,
JSONObject response) {
AnUtils.setCurrentClientId(clientId);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
try {
wrapper.anIM.connect(clientId);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.i(logTag, "clientId retrived error: "
+ arg0.getException().getErrorCode());
arg0.getException().getInnerException().printStackTrace();
}
}
@Override
public void getClientsStatus(AnIMGetClientsStatusCallbackData arg0) {
}
@Override
public void getSessionInfo(AnIMGetSessionInfoCallbackData arg0) {
}
// 回调函数。获取群组信息的回调函数
@SuppressWarnings("unchecked")
@Override
public void getTopicInfo(AnIMGetTopicInfoCallbackData arg0) {
Log.i(logTag, "topicInfo retrived");
if (arg0.getException() != null) {
verifyIfMyTopic(null);
} else {
verifyIfMyTopic(arg0.getParties());
}
}
// 回调函数。获取所有群组列表的回调函数
@SuppressWarnings("unchecked")
@Override
public void getTopicList(AnIMGetTopicListCallbackData arg0) {
if (delegate != null) {
if (!arg0.isError()) {
delegate.getTopicsDone(arg0.getTopicList());
} else {
delegate.getTopicsDone(null);
arg0.getException().printStackTrace();
}
}
}
// 回调函数。某条消息发送成功/失败的回调函数
@Override
public void messageSent(AnIMMessageSentCallbackData arg0) {
if (arg0.getException() != null) {
String messageId = arg0.getMsgId();
tmpMessages.remove(messageId);
if (messageListActivity != null) {
messageListActivity.onMessageSent(null);
}
if (chatActivity != null) {
chatActivity.onChatSent(null);
}
} else {
final String messageId = arg0.getMsgId();
if (messageId != null) {
Message message = tmpMessages.get(messageId);
if (message != null) {
message.isUnsent = false;
DBManager.writeMessage(message);
tmpMessages.remove(messageId);
if (messageListActivity != null) {
messageListActivity.onMessageSent(messageId);
}
}
DBManager.updateChatStatus(messageId, false, "sent");
if (chatActivity != null) {
chatActivity.onChatSent(messageId);
}
}
}
}
// 回调函数。收到来自某个用户的binary数据时的回调函数
@SuppressWarnings("unchecked")
@Override
public void receivedBinary(AnIMBinaryCallbackData arg0) {
Log.i(logTag, "received binary: " + arg0.getMsgId());
try {
Map<String, String> customData = arg0.getCustomData();
String username = customData.get("username");
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Chat chat = new Chat();
chat.type = arg0.getFileType();
chat.fromClientId = arg0.getFrom();
List<String> p = new ArrayList<String>();
p.add(AnUtils.getCurrentClientId());
p.add(arg0.getFrom());
Collections.sort(p);
chat.parties = StringUtils.join(p, ",");
chat.messageId = arg0.getMsgId();
chat.status = "unread";
chat.income = true;
chat.time = AnUtils.getTimeString(time);
chat.realname = username;
if (chat.type.equals("location")) {
chat.latitude = Double.valueOf(customData.get("latitude")
.toString());
chat.longitude = Double.valueOf(customData.get("longitude")
.toString());
} else {
chat.binary = arg0.getContent();
}
saveRecievedBinaryMessage(chat, p);
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveRecievedBinaryMessage(Chat chat, List<String> parties) {
DBManager.addChat(chat);
parties.remove(AnUtils.getCurrentClientId());
boolean existing = DBManager.setSessionUnread(parties, chat.time, "收到了新" + chat.type);
if (existing) {
if ((chatActivity == null && sessionActivity == null)
|| (chatActivity == null && !sessionActivity.alive)
|| (chatActivity != null && !chatActivity.alive)) {
AnUtils.showNotification(thisContext, "session");
return;
}
if (chatActivity != null && chatActivity.alive) {
chatActivity.onReceivedChat();
Log.i(logTag, "sendReadACK messageReceived");
wrapper.sendReadACKToClients(parties, chat.messageId);
}
if (sessionActivity != null && sessionActivity.alive) {
sessionActivity.initData();
}
} else {
DBManager.addSession(parties, chat.realname, chat.time, "收到了新" + chat.type, "unread");
}
}
// 回调函数。收到来自某个用户的文本消息时的回调函数
@SuppressWarnings("unchecked")
@Override
public void receivedMessage(AnIMMessageCallbackData arg0) {
Log.i(logTag, "received message: " + arg0.getMessage());
try {
Map<String, String> customData = arg0.getCustomData();
String username = customData.get("username");
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Chat chat = new Chat();
chat.type = "text";
chat.fromClientId = arg0.getFrom();
List<String> p = new ArrayList<String>();
p.add(AnUtils.getCurrentClientId());
p.add(arg0.getFrom());
Collections.sort(p);
chat.parties = StringUtils.join(p, ",");
chat.message = arg0.getMessage();
chat.messageId = arg0.getMsgId();
chat.status = "unread";
chat.income = true;
chat.time = AnUtils.getTimeString(time);
chat.realname = username;
saveReceivedMessage(chat, p);
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveReceivedMessage(Chat chat, List<String> parties) {
DBManager.addChat(chat);
parties.remove(AnUtils.getCurrentClientId());
boolean existing = DBManager.setSessionUnread(parties, chat.time, chat.message);
if (existing) {
if ((chatActivity == null && sessionActivity == null)
|| (chatActivity == null && !sessionActivity.alive)
|| (chatActivity != null && !chatActivity.alive)) {
AnUtils.showNotification(thisContext, "session");
return;
}
if (chatActivity != null && chatActivity.alive) {
chatActivity.onReceivedChat();
Log.i(logTag, "sendReadACK messageReceived");
wrapper.sendReadACKToClients(parties, chat.messageId);
}
if (sessionActivity != null && sessionActivity.alive) {
sessionActivity.initData();
}
} else {
DBManager.addSession(parties, chat.realname, chat.time, chat.message, "unread");
}
}
@Override
public void receivedNotice(AnIMNoticeCallbackData arg0) {
}
// 回调函数。当某条发送出的消息已经被对方阅读的回调函数
@Override
public void receivedReadACK(AnIMReadACKCallbackData arg0) {
Log.i(logTag,
"message: " + arg0.getMsgId() + " read by: " + arg0.getFrom());
DBManager.updateChatStatus(arg0.getMsgId(), false, "read");
if (chatActivity != null && chatActivity.alive) {
chatActivity.onChatRead();
}
}
// 回调函数。当某条发送出的消息已经被对方接收到的回调函数
@Override
public void receivedReceiveACK(AnIMReceiveACKCallbackData arg0) {
Log.i(logTag,
"message: " + arg0.getMsgId() + " recevied by: "
+ arg0.getFrom());
DBManager.updateChatStatus(arg0.getMsgId(), false, "received");
if (chatActivity != null && chatActivity.alive) {
chatActivity.onChatReceived();
}
}
// 回调函数。收到来自某个群组的binary数据时的回调函数
@SuppressWarnings("unchecked")
@Override
public void receivedTopicBinary(AnIMTopicBinaryCallbackData arg0) {
String messageId = arg0.getMsgId();
byte[] contentData = arg0.getContent();
String fileType = arg0.getFileType();
String topicId = arg0.getTopic();
Map<String, String> customData = arg0.getCustomData();
String realname = customData.get("realname");
String username = customData.get("username");
if (realname == null) {
realname = username;
}
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Message message = new Message();
message.messageId = messageId;
message.topicId = topicId;
message.realname = realname;
message.username = username;
message.timestamp = time;
message.isUnread = true;
message.isIncoming = true;
message.isUnsent = false;
message.isError = false;
if (fileType.equals("image")) {
message.imageData = contentData;
message.type = EntityType.ET_IMAGE;
} else if (fileType.equals("audio")) {
message.audioData = contentData;
message.type = EntityType.ET_AUDIO;
}
DBManager.writeMessage(message);
if (messageListActivity != null) {
messageListActivity.onMessage(message);
}
if (topicListActivity != null) {
topicListActivity.onMessage(message);
}
}
// 回调函数。收到来自某个群组的文本消息时的回调函数
@SuppressWarnings("unchecked")
@Override
public void receivedTopicMessage(AnIMTopicMessageCallbackData arg0) {
String messageId = arg0.getMsgId();
String content = arg0.getMessage();
String topicId = arg0.getTopic();
Map<String, String> customData = arg0.getCustomData();
String realname = customData.get("realname");
String username = customData.get("username");
if (realname == null) {
realname = username;
}
double timeDouble = Double.parseDouble(customData.get("time"));
long longTime = (long) timeDouble * 1000;
Date time = new Date(longTime);
Message message = new Message();
message.messageId = messageId;
message.content = content;
message.topicId = topicId;
message.realname = realname;
message.username = username;
message.timestamp = time;
message.isUnread = true;
message.isIncoming = true;
message.isUnsent = false;
message.isError = false;
message.type = EntityType.ET_TEXT;
DBManager.writeMessage(message);
if (messageListActivity != null) {
messageListActivity.onMessage(message);
}
if (topicListActivity != null) {
topicListActivity.onMessage(message);
}
}
// 回调函数。从某个群组将某个(某些)用户移除的回调函数
@Override
public void removeClientsFromTopic(AnIMRemoveClientsCallbackData arg0) {
if (messageListActivity != null) {
if (arg0.getException() != null) {
messageListActivity.onQuitTopic(false);
} else {
messageListActivity.onQuitTopic(true);
}
}
}
// 回调函数。当IM与服务器连接状态有更新时的回调函数
@Override
public void statusUpdate(AnIMStatusUpdateCallbackData arg0) {
Log.i(logTag, " statusUpdate");
if (arg0.getException() != null) {
Log.i(logTag, "statusUpdate error: "
+ arg0.getException().getErrorCode());
status = false;
int ec = arg0.getException().getErrorCode();
if (ec == 3102 || ec == 3105) {
return;
}
}
if (arg0.getStatus() == AnIMStatus.OFFLINE) {
Log.i(logTag, "statusUpdate OFFLINE");
status = false;
if (!willDisconnect && retryCount > 0) {
try {
retryCount--;
if (wrapper.getActiveNetwork(thisContext) == null) {
return;
}
wrapper.anIM.connect(AnUtils.getCurrentClientId());
} catch (Exception e) {
e.printStackTrace();
}
} else {
retryCount = 1;
}
} else {
Log.i(logTag, "statusUpdate ONLINE");
status = true;
if (AnUtils.getAnId() == null) {
if (thisAnId != null) {
Log.i(logTag, "bind anPush");
try {
wrapper.anIM.bindAnPushService(thisAnId,
AnUtils.AppKey, AnPushType.AnPushTypeAndroid);
} catch (ArrownockException e) {
e.printStackTrace();
}
}
}
// fetch all offline messages when open the app
getOfflineMessages();
getTopicOfflineMessages();
}
}
// 解除Push服务的回调函数
@Override
public void unbindAnPushService(AnIMUnbindAnPushServiceCallbackData arg0) {
Log.i(logTag, "didUnbindPush");
try {
willDisconnect = true;
wrapper.anIM.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void updateTopic(AnIMUpdateTopicCallbackData arg0) {
// the topic has been updated
}
}