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); // } }