package com.mogujie.tt.imlib;
import java.util.ArrayList;
import java.util.List;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.view.View;
import com.mogujie.tt.R;
import com.mogujie.tt.imlib.common.ConfigDefs;
import com.mogujie.tt.imlib.proto.ContactEntity;
import com.mogujie.tt.imlib.proto.GroupEntity;
import com.mogujie.tt.imlib.proto.MessageEntity;
import com.mogujie.tt.imlib.utils.IMContactHelper;
import com.mogujie.tt.imlib.utils.IMUIHelper;
import com.mogujie.tt.imlib.utils.IMUIHelper.SessionInfo;
import com.mogujie.tt.log.Logger;
import com.mogujie.tt.ui.activity.MessageActivity;
import com.mogujie.tt.ui.utils.IMServiceHelper;
import com.mogujie.tt.ui.utils.IMServiceHelper.OnIMServiceListner;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageSize;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
public class IMNotificationManager extends IMManager
implements
OnIMServiceListner {
private static IMNotificationManager inst;
private Logger logger = Logger.getLogger(IMNotificationManager.class);
private IMServiceHelper imServiceHelper = new IMServiceHelper();
public static IMNotificationManager instance() {
synchronized (IMNotificationManager.class) {
if (inst == null) {
inst = new IMNotificationManager();
}
return inst;
}
}
private IMNotificationManager() {
}
public void register() {
logger.d("notification#regisgter");
List<String> actions = new ArrayList<String>();
actions.add(IMActions.ACTION_MSG_RECV);
imServiceHelper.registerActions(ctx, actions, IMServiceHelper.INTENT_NO_PRIORITY, this);
}
@Override
public void onAction(String action, Intent intent,
BroadcastReceiver broadcastReceiver) {
logger.d("notification#onAction action:%s", action);
if (action.equals(IMActions.ACTION_MSG_RECV)) {
handleMsgRecv(intent);
}
}
public String getSessionAvatarUrl(int sessionType, String sessionId) {
String url = "";
if (sessionType == IMSession.SESSION_P2P) {
ContactEntity contact = IMContactManager.instance().findContact(sessionId);
if (contact == null) {
logger.d("notification#no such contact by id:%s", sessionId);
return "";
}
url = contact.avatarUrl;
} else {
GroupEntity group = IMGroupManager.instance().findGroup(sessionId);
if (group == null) {
logger.d("notification#no such group by id:%s", sessionId);
return "";
}
url = group.avatarUrl;
}
return IMContactHelper.getRealAvatarUrl(url);
}
private void handleMsgRecv(Intent intent) {
logger.d("notification#recv unhandled message");
if (!shouldShowNotification()) {
logger.d("notification#shouldShowNotification is false, return");
return;
}
SessionInfo sessionInfo = IMUIHelper.getSessionInfoFromIntent(intent);
String sessionId = sessionInfo.getSessionId();
logger.d("notification#msg no one handled, sessionId:%s, sessionType:%d", sessionId, sessionInfo.getSessionType());
final MessageEntity msg = IMUnreadMsgManager.instance().getLatestMessage(sessionId);
if (msg == null) {
logger.e("notification#getLatestMessage failed for sessionId:%s", sessionId);
return;
}
int sessionTotalMsgCnt = IMUnreadMsgManager.instance().getUnreadMsgListCnt(sessionId);
logger.d("notification#getUnreadMsgListCnt:%d", sessionTotalMsgCnt);
showNotification(msg, sessionId, sessionTotalMsgCnt);
}
private boolean shouldShowNotification() {
if (IMConfigurationManager.instance().getBoolean(ConfigDefs.CATEGORY_GLOBAL, ConfigDefs.KEY_NOTIFICATION_NO_DISTURB, ConfigDefs.DEF_VALUE_NOTIFICATION_NO_DISTURB)) {
logger.d("notification#global setting: no disturb");
return false;
}
return true;
}
private boolean shouldUseNotificationSound() {
return IMConfigurationManager.instance().getBoolean(ConfigDefs.CATEGORY_GLOBAL, ConfigDefs.KEY_NOTIFICATION_GOT_SOUND, ConfigDefs.DEF_VALUE_NOTIFICATION_GOT_SOUND);
}
private boolean shouldUseNotificationVibration() {
return IMConfigurationManager.instance().getBoolean(ConfigDefs.CATEGORY_GLOBAL, ConfigDefs.KEY_NOTIFICATION_GOT_VIBRATION, ConfigDefs.DEF_VALUE_NOTIFICATION_GOT_VIBRATION);
}
private void showNotification(final MessageEntity latestMsg,
final String sessionId, final int sessionTotalMsgCnt) {
//todo eric need to set the exact size of the big icon
ImageSize targetSize = new ImageSize(128, 128);
String avatarUrl = getSessionAvatarUrl(latestMsg.sessionType, sessionId);
logger.d("notification#notification avatarUrl:%s", avatarUrl);
ImageLoader.getInstance().loadImage(avatarUrl, targetSize, null, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view,
Bitmap loadedImage) {
logger.d("notification#icon onLoadingComplete");
//holder.image.setImageBitmap(loadedImage);
showInNotificationBar(latestMsg, sessionId, latestMsg.sessionType, loadedImage, sessionTotalMsgCnt);
}
@Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
logger.d("notification#icon onLoadingFailed");
showInNotificationBar(latestMsg, sessionId, latestMsg.sessionType, null, sessionTotalMsgCnt);
}
});
}
private void showInNotificationBar(MessageEntity msg, String sessionId,
int sessionType, Bitmap iconBitmap, int sessionTotalMsgCnt) {
logger.d("notification#showInNotificationBar msg:%s, sessionId:%s, sessionType:%d, sessionTotalMsgCnt:%d", msg, sessionId, sessionType, sessionTotalMsgCnt);
NotificationManager notifyMgr = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
if (notifyMgr == null) {
return;
}
Builder builder = new NotificationCompat.Builder(ctx);
builder.setContentTitle(getNotificationTitle(msg));
builder.setContentText(getNotificationContentText(sessionTotalMsgCnt, msg));
builder.setSmallIcon(R.drawable.tt_logo);
builder.setTicker(getRollingText(sessionTotalMsgCnt, msg, false));
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
//this is the content near the right bottom side
//builder.setContentInfo("content info");
if (shouldUseNotificationVibration()) {
//delay 0ms, vibrate 200ms, delay 250ms, vibrate 200ms
long[] vibrate = {0, 200, 250, 200};
builder.setVibrate(vibrate);
} else {
logger.d("notification#setting is not using vibration");
}
//sound
if (shouldUseNotificationSound()) {
builder.setDefaults(Notification.DEFAULT_SOUND);
} else {
logger.d("notification#setting is not using sound");
}
if (iconBitmap != null) {
logger.d("notification#fetch icon from network ok");
builder.setLargeIcon(iconBitmap);
} else {
//todo eric default avatar is too small, need big size(128 * 128)
Bitmap defaultBitmap = BitmapFactory.decodeResource(ctx.getResources(), IMUIHelper.getDefaultAvatarResId(msg.sessionType));
if (defaultBitmap != null) {
builder.setLargeIcon(defaultBitmap);
}
}
Intent intent = new Intent(ctx, MessageActivity.class);
IMUIHelper.setSessionInIntent(intent, sessionId, sessionType);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
notifyMgr.notify(Integer.parseInt(sessionId), notification);
}
private String getNotificationContent(MessageEntity msg) {
// todo eric i18n
if (msg.isTextType()) {
return msg.getText();
} else if (msg.isAudioType()) {
return "[语音]";
} else if (msg.isImage()) {
return "[图片]";
} else {
return "错误消息图片";
}
}
private String getRollingText(int sessionTotalMsgCnt, MessageEntity msg,
boolean noName) {
String msgContent = getNotificationContent(msg);
String contactName = msg.fromId;
ContactEntity contact = IMContactManager.instance().findContact(msg.fromId);
if (contact == null) {
logger.e("notification#no contact id:%s", msg.fromId);
} else {
contactName = contact.name;
}
String unit = ctx.getString(R.string.msg_cnt_unit);
if (noName) {
return String.format("[%d%s] %s", sessionTotalMsgCnt, unit, msgContent);
} else {
return String.format("[%d%s]%s: %s", sessionTotalMsgCnt, unit, contactName, msgContent);
}
}
private String getNotificationTitle(MessageEntity msg) {
if (msg.isGroupMsg()) {
GroupEntity group = IMGroupManager.instance().findGroup(msg.toId);
if (group == null) {
logger.e("notification#no such group id:%s", msg.toId);
return "no such group:" + msg.toId;
}
return group.name;
} else if (msg.isP2PMsg()) {
ContactEntity contact = IMContactManager.instance().findContact(msg.fromId);
if (contact == null) {
logger.e("notification#no such contact id:%s", msg.fromId);
return "no such contact:" + msg.fromId;
}
return contact.name;
}
return "wrong message type:" + msg.fromId + " " + msg.toId;
}
private String getNotificationContentText(int sessionTotalMsgCnt,
MessageEntity msg) {
if (msg.isGroupMsg()) {
return getRollingText(sessionTotalMsgCnt, msg, false);
} else {
return getRollingText(sessionTotalMsgCnt, msg, true);
}
}
@Override
public void onIMServiceConnected() {
}
// private void oldNotification() {
// Notification notification = new Notification();
//
// //notification.icon = IMUIHelper.getDefaultAvatarResId(msg.sessionType);
// if (icon == null) {
// logger.e("notification#icon is null");
// notification.icon = IMUIHelper.getDefaultAvatarResId(msg.sessionType);
// } else {
// notification.largeIcon = icon;
// }
//
// //notification.icon = IMUIHelper.getDefaultAvatarResId(msg.sessionType);
//
// //delay 0ms, vibrate 200ms, delay 250ms, vibrate 200ms
// long[] vibrate = {0, 200, 250, 200};
// notification.vibrate = vibrate;
//
// notification.when = System.currentTimeMillis();
//
// notification.flags |= Notification.FLAG_AUTO_CANCEL;
//
// // rolling text
// notification.tickerText = getRollingText(msg, false);
// notification.defaults = Notification.DEFAULT_SOUND;
//
// Intent intent = new Intent(ctx, MessageActivity.class);
// IMUIHelper.setSessionInIntent(intent, sessionId, sessionType);
//
// PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_ONE_SHOT);
// notification.setLatestEventInfo(ctx, getNotificationTitle(msg), getNotificationContentText(msg), pendingIntent);
// notifyMgr.notify(Integer.parseInt(sessionId), notification);
// }
}