/************************************************************
* * EaseMob CONFIDENTIAL
* __________________
* Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of EaseMob Technologies.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from EaseMob Technologies.
*/
package com.easemob.applib.model;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat;
import com.easemob.applib.controller.HXSDKHelper;
import com.easemob.chat.EMChatManager;
import com.easemob.chat.EMMessage;
import com.easemob.util.EMLog;
import com.easemob.util.EasyUtils;
/**
* 新消息提醒class
* 2.1.8把新消息提示相关的api移除出sdk,方便开发者自由修改
* 开发者也可以继承此类实现相关的接口
*
* this class is subject to be inherited and implement the relative APIs
*/
public class HXNotifier {
private final static String TAG = "notify";
Ringtone ringtone = null;
protected final static String[] msg_eng = { "sent a message", "sent a picture", "sent a voice",
"sent location message", "sent a video", "sent a file", "%1 contacts sent %2 messages"
};
protected final static String[] msg_ch = { "发来一条消息", "发来一张图片", "发来一段语音", "发来位置信息", "发来一个视频", "发来一个文件",
"%1个联系人发来%2条消息"
};
protected static int notifyID = 0525; // start notification id
protected static int foregroundNotifyID = 0555;
protected NotificationManager notificationManager = null;
protected HashSet<String> fromUsers = new HashSet<String>();
protected int notificationNum = 0;
protected Context appContext;
protected String packageName;
protected String[] msgs;
protected long lastNotifiyTime;
protected AudioManager audioManager;
protected Vibrator vibrator;
protected HXNotificationInfoProvider notificationInfoProvider;
public HXNotifier() {
}
/**
* 开发者可以重载此函数
* this function can be override
* @param context
* @return
*/
public HXNotifier init(Context context){
appContext = context;
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
packageName = appContext.getApplicationInfo().packageName;
if (Locale.getDefault().getLanguage().equals("zh")) {
msgs = msg_ch;
} else {
msgs = msg_eng;
}
audioManager = (AudioManager) appContext.getSystemService(Context.AUDIO_SERVICE);
vibrator = (Vibrator) appContext.getSystemService(Context.VIBRATOR_SERVICE);
return this;
}
/**
* 开发者可以重载此函数
* this function can be override
*/
public void reset(){
resetNotificationCount();
cancelNotificaton();
}
void resetNotificationCount() {
notificationNum = 0;
fromUsers.clear();
}
void cancelNotificaton() {
if (notificationManager != null)
notificationManager.cancel(notifyID);
}
/**
* 处理新收到的消息,然后发送通知
*
* 开发者可以重载此函数
* this function can be override
*
* @param message
*/
public synchronized void onNewMsg(EMMessage message) {
if(EMChatManager.getInstance().isSlientMessage(message)){
return;
}
// 判断app是否在后台
if (!EasyUtils.isAppRunningForeground(appContext)) {
EMLog.d(TAG, "app is running in backgroud");
sendNotification(message, false);
} else {
sendNotification(message, true);
}
viberateAndPlayTone(message);
}
public synchronized void onNewMesg(List<EMMessage> messages) {
if(EMChatManager.getInstance().isSlientMessage(messages.get(messages.size()-1))){
return;
}
// 判断app是否在后台
if (!EasyUtils.isAppRunningForeground(appContext)) {
EMLog.d(TAG, "app is running in backgroud");
sendNotification(messages, false);
} else {
sendNotification(messages, true);
}
viberateAndPlayTone(messages.get(messages.size()-1));
}
/**
* 发送通知栏提示
* This can be override by subclass to provide customer implementation
* @param messages
* @param isForeground
*/
protected void sendNotification (List<EMMessage> messages, boolean isForeground){
for(EMMessage message : messages){
if(!isForeground){
notificationNum++;
fromUsers.add(message.getFrom());
}
}
sendNotification(messages.get(messages.size()-1), isForeground, false);
}
protected void sendNotification (EMMessage message, boolean isForeground){
sendNotification(message, isForeground, true);
}
/**
* 发送通知栏提示
* This can be override by subclass to provide customer implementation
* @param message
*/
protected void sendNotification(EMMessage message, boolean isForeground, boolean numIncrease) {
String username = message.getFrom();
try {
String notifyText = username + " ";
switch (message.getType()) {
case TXT:
notifyText += msgs[0];
break;
case IMAGE:
notifyText += msgs[1];
break;
case VOICE:
notifyText += msgs[2];
break;
case LOCATION:
notifyText += msgs[3];
break;
case VIDEO:
notifyText += msgs[4];
break;
case FILE:
notifyText += msgs[5];
break;
}
PackageManager packageManager = appContext.getPackageManager();
String appname = (String) packageManager.getApplicationLabel(appContext.getApplicationInfo());
// notification titile
String contentTitle = appname;
if (notificationInfoProvider != null) {
String customNotifyText = notificationInfoProvider.getDisplayedText(message);
String customCotentTitle = notificationInfoProvider.getTitle(message);
if (customNotifyText != null){
// 设置自定义的状态栏提示内容
notifyText = customNotifyText;
}
if (customCotentTitle != null){
// 设置自定义的通知栏标题
contentTitle = customCotentTitle;
}
}
// create and send notificaiton
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(appContext)
.setSmallIcon(appContext.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true);
Intent msgIntent = appContext.getPackageManager().getLaunchIntentForPackage(packageName);
if (notificationInfoProvider != null) {
// 设置自定义的notification点击跳转intent
msgIntent = notificationInfoProvider.getLaunchIntent(message);
}
PendingIntent pendingIntent = PendingIntent.getActivity(appContext, notifyID, msgIntent,PendingIntent.FLAG_UPDATE_CURRENT);
if(numIncrease){
// prepare latest event info section
if(!isForeground){
notificationNum++;
fromUsers.add(message.getFrom());
}
}
int fromUsersNum = fromUsers.size();
String summaryBody = msgs[6].replaceFirst("%1", Integer.toString(fromUsersNum)).replaceFirst("%2",Integer.toString(notificationNum));
if (notificationInfoProvider != null) {
// lastest text
String customSummaryBody = notificationInfoProvider.getLatestText(message, fromUsersNum,notificationNum);
if (customSummaryBody != null){
summaryBody = customSummaryBody;
}
// small icon
int smallIcon = notificationInfoProvider.getSmallIcon(message);
if (smallIcon != 0){
mBuilder.setSmallIcon(smallIcon);
}
}
mBuilder.setContentTitle(contentTitle);
mBuilder.setTicker(notifyText);
mBuilder.setContentText(summaryBody);
mBuilder.setContentIntent(pendingIntent);
// mBuilder.setNumber(notificationNum);
Notification notification = mBuilder.build();
if (isForeground) {
notificationManager.notify(foregroundNotifyID, notification);
notificationManager.cancel(foregroundNotifyID);
} else {
notificationManager.notify(notifyID, notification);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 手机震动和声音提示
*/
public void viberateAndPlayTone(EMMessage message) {
if(message != null){
if(EMChatManager.getInstance().isSlientMessage(message)){
return;
}
}
HXSDKModel model = HXSDKHelper.getInstance().getModel();
if(!model.getSettingMsgNotification()){
return;
}
if (System.currentTimeMillis() - lastNotifiyTime < 1000) {
// received new messages within 2 seconds, skip play ringtone
return;
}
try {
lastNotifiyTime = System.currentTimeMillis();
// 判断是否处于静音模式
if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {
EMLog.e(TAG, "in slient mode now");
return;
}
if(model.getSettingMsgVibrate()){
long[] pattern = new long[] { 0, 180, 80, 120 };
vibrator.vibrate(pattern, -1);
}
if(model.getSettingMsgSound()){
if (ringtone == null) {
Uri notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
ringtone = RingtoneManager.getRingtone(appContext, notificationUri);
if (ringtone == null) {
EMLog.d(TAG, "cant find ringtone at:" + notificationUri.getPath());
return;
}
}
if (!ringtone.isPlaying()) {
String vendor = Build.MANUFACTURER;
ringtone.play();
// for samsung S3, we meet a bug that the phone will
// continue ringtone without stop
// so add below special handler to stop it after 3s if
// needed
if (vendor != null && vendor.toLowerCase().contains("samsung")) {
Thread ctlThread = new Thread() {
public void run() {
try {
Thread.sleep(3000);
if (ringtone.isPlaying()) {
ringtone.stop();
}
} catch (Exception e) {
}
}
};
ctlThread.run();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置NotificationInfoProvider
*
* @param provider
*/
public void setNotificationInfoProvider(HXNotificationInfoProvider provider) {
notificationInfoProvider = provider;
}
public interface HXNotificationInfoProvider {
/**
* 设置发送notification时状态栏提示新消息的内容(比如Xxx发来了一条图片消息)
*
* @param message
* 接收到的消息
* @return null为使用默认
*/
String getDisplayedText(EMMessage message);
/**
* 设置notification持续显示的新消息提示(比如2个联系人发来了5条消息)
*
* @param message
* 接收到的消息
* @param fromUsersNum
* 发送人的数量
* @param messageNum
* 消息数量
* @return null为使用默认
*/
String getLatestText(EMMessage message, int fromUsersNum, int messageNum);
/**
* 设置notification标题
*
* @param message
* @return null为使用默认
*/
String getTitle(EMMessage message);
/**
* 设置小图标
*
* @param message
* @return 0使用默认图标
*/
int getSmallIcon(EMMessage message);
/**
* 设置notification点击时的跳转intent
*
* @param message
* 显示在notification上最近的一条消息
* @return null为使用默认
*/
Intent getLaunchIntent(EMMessage message);
}
}