public void add(MessageEntity msg) {
    // 更新session list中的msg信息
    // 更新未读消息计数
    if (msg == null) {
      logger.d("unread#unreadMgr#add msg is null!");
      return;
    }
    // isFirst场景:出现一条未读消息,出现小红点,需要触发 [免打扰的情况下]
    boolean isFirst = false;
    logger.d("unread#unreadMgr#add unread msg:%s", msg);
    UnreadEntity unreadEntity;
    int loginId = IMLoginManager.instance().getLoginId();
    String sessionKey = msg.getSessionKey();
    boolean isSend = msg.isSend(loginId);
    if (isSend) {
      IMNotificationManager.instance().cancelSessionNotifications(sessionKey);
      return;
    }

    if (unreadMsgMap.containsKey(sessionKey)) {
      unreadEntity = unreadMsgMap.get(sessionKey);
      // 判断最后一条msgId是否相同
      if (unreadEntity.getLaststMsgId() == msg.getMsgId()) {
        return;
      }
      unreadEntity.setUnReadCnt(unreadEntity.getUnReadCnt() + 1);
    } else {
      isFirst = true;
      unreadEntity = new UnreadEntity();
      unreadEntity.setUnReadCnt(1);
      unreadEntity.setPeerId(msg.getPeerId(isSend));
      unreadEntity.setSessionType(msg.getSessionType());
      unreadEntity.buildSessionKey();
    }

    unreadEntity.setLatestMsgData(msg.getMessageDisplay());
    unreadEntity.setLaststMsgId(msg.getMsgId());
    addIsForbidden(unreadEntity);

    /** 放入manager 状态中 */
    unreadMsgMap.put(unreadEntity.getSessionKey(), unreadEntity);

    /** 没有被屏蔽才会发送广播 */
    if (!unreadEntity.isForbidden() || isFirst) {
      UnreadEvent unreadEvent = new UnreadEvent();
      unreadEvent.event = UnreadEvent.Event.UNREAD_MSG_RECEIVED;
      unreadEvent.entity = unreadEntity;
      triggerEvent(unreadEvent);
    }
  }
  public void onRepUnreadMsgContactList(IMMessage.IMUnreadMsgCntRsp unreadMsgCntRsp) {
    logger.i("unread#2onRepUnreadMsgContactList");
    totalUnreadCount = unreadMsgCntRsp.getTotalCnt();
    List<IMBaseDefine.UnreadInfo> unreadInfoList = unreadMsgCntRsp.getUnreadinfoListList();
    logger.i(
        "unread#unreadMsgCnt:%d, unreadMsgInfoCnt:%d", unreadInfoList.size(), totalUnreadCount);

    for (IMBaseDefine.UnreadInfo unreadInfo : unreadInfoList) {
      UnreadEntity unreadEntity = ProtoBuf2JavaBean.getUnreadEntity(unreadInfo);
      // 屏蔽的设定
      addIsForbidden(unreadEntity);
      unreadMsgMap.put(unreadEntity.getSessionKey(), unreadEntity);
    }
    triggerEvent(new UnreadEvent(UnreadEvent.Event.UNREAD_MSG_LIST_OK));
  }
  private void handleMsgRecv(UnreadEntity entity) {
    logger.d("notification#recv unhandled message");
    int peerId = entity.getPeerId();
    int sessionType = entity.getSessionType();
    logger.d("notification#msg no one handled, peerId:%d, sessionType:%d", peerId, sessionType);

    // 判断是否设定了免打扰
    if (entity.isForbidden()) {
      logger.d("notification#GROUP_STATUS_SHIELD");
      return;
    }

    // PC端是否登陆 取消 【暂时先关闭】
    //        if(IMLoginManager.instance().isPcOnline()){
    //            logger.d("notification#isPcOnline");
    //            return;
    //        }

    // 全局开关
    boolean globallyOnOff =
        configurationSp.getCfg(
            SysConstant.SETTING_GLOBAL, ConfigurationSp.CfgDimension.NOTIFICATION);
    if (globallyOnOff) {
      logger.d("notification#shouldGloballyShowNotification is false, return");
      return;
    }

    // 单独的设置
    boolean singleOnOff =
        configurationSp.getCfg(entity.getSessionKey(), ConfigurationSp.CfgDimension.NOTIFICATION);
    if (singleOnOff) {
      logger.d("notification#shouldShowNotificationBySession is false, return");
      return;
    }

    // if the message is a multi login message which send from another terminal,not need notificate
    // to status bar
    // 判断是否是自己的消息
    if (IMLoginManager.instance().getLoginId() != peerId) {
      showNotification(entity);
    }
  }
  private void showNotification(final UnreadEntity unreadEntity) {
    // todo eric need to set the exact size of the big icon
    // 服务端有些特定的支持 尺寸是不是要调整一下 todo 100*100  下面的就可以不要了
    ImageSize targetSize = new ImageSize(80, 80);
    int peerId = unreadEntity.getPeerId();
    int sessionType = unreadEntity.getSessionType();
    String avatarUrl = "";
    String title = "";
    String content = unreadEntity.getLatestMsgData();
    String unit = ctx.getString(R.string.msg_cnt_unit);
    int totalUnread = unreadEntity.getUnReadCnt();

    if (unreadEntity.getSessionType() == DBConstant.SESSION_TYPE_SINGLE) {
      UserEntity contact = IMContactManager.instance().findContact(peerId);
      if (contact != null) {
        title = contact.getMainName();
        avatarUrl = contact.getAvatar();
      } else {
        title = "User_" + peerId;
        avatarUrl = "";
      }

    } else {
      GroupEntity group = IMGroupManager.instance().findGroup(peerId);
      if (group != null) {
        title = group.getMainName();
        avatarUrl = group.getAvatar();
      } else {
        title = "Group_" + peerId;
        avatarUrl = "";
      }
    }
    // 获取头像
    avatarUrl = IMUIHelper.getRealAvatarUrl(avatarUrl);
    final String ticker = String.format("[%d%s]%s: %s", totalUnread, unit, title, content);
    final int notificationId = getSessionNotificationId(unreadEntity.getSessionKey());
    final Intent intent = new Intent(ctx, MessageActivity.class);
    intent.putExtra(IntentConstant.KEY_SESSION_KEY, unreadEntity.getSessionKey());

    logger.d("notification#notification avatarUrl:%s", avatarUrl);
    final String finalTitle = title;
    ImageLoader.getInstance()
        .loadImage(
            avatarUrl,
            targetSize,
            null,
            new SimpleImageLoadingListener() {

              @Override
              public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                logger.d("notification#icon onLoadComplete");
                // holder.image.setImageBitmap(loadedImage);
                showInNotificationBar(finalTitle, ticker, loadedImage, notificationId, intent);
              }

              @Override
              public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                logger.d("notification#icon onLoadFailed");
                // 服务器支持的格式有哪些
                // todo eric default avatar is too small, need big size(128 * 128)
                Bitmap defaultBitmap =
                    BitmapFactory.decodeResource(
                        ctx.getResources(),
                        IMUIHelper.getDefaultAvatarResId(unreadEntity.getSessionType()));
                showInNotificationBar(finalTitle, ticker, defaultBitmap, notificationId, intent);
              }
            });
  }