/************************************************************ * * Hyphenate CONFIDENTIAL * __________________ * Copyright (C) 2016 Hyphenate Inc. All rights reserved. * * NOTICE: All information contained herein is, and remains * the property of Hyphenate Inc. * Dissemination of this information or reproduction of this material * is strictly forbidden unless prior written permission is obtained * from Hyphenate Inc. */ package com.fanxin.easeui.model; import java.util.HashSet; import java.util.List; import java.util.Locale; import com.hyphenate.chat.EMClient; import com.hyphenate.chat.EMMessage; import com.fanxin.easeui.controller.EaseUI; import com.fanxin.easeui.controller.EaseUI.EaseSettingsProvider; import com.hyphenate.util.EMLog; import com.hyphenate.util.EasyUtils; 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; /** * new message notifier class * * this class is subject to be inherited and implement the relative APIs */ public class EaseNotifier { 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 EaseNotificationInfoProvider notificationInfoProvider; public EaseNotifier() { } /** * this function can be override * @param context * @return */ public EaseNotifier 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); } /** * handle the new message * this function can be override * * @param message */ public synchronized void onNewMsg(EMMessage message) { if(EMClient.getInstance().chatManager().isSlientMessage(message)){ return; } EaseSettingsProvider settingsProvider = EaseUI.getInstance().getSettingsProvider(); if(!settingsProvider.isMsgNotifyAllowed(message)){ return; } // check if app running background if (!EasyUtils.isAppRunningForeground(appContext)) { EMLog.d(TAG, "app is running in backgroud"); sendNotification(message, false); } else { sendNotification(message, true); } vibrateAndPlayTone(message); } public synchronized void onNewMesg(List<EMMessage> messages) { if(EMClient.getInstance().chatManager().isSlientMessage(messages.get(messages.size()-1))){ return; } EaseSettingsProvider settingsProvider = EaseUI.getInstance().getSettingsProvider(); if(!settingsProvider.isMsgNotifyAllowed(null)){ return; } // check if app running background if (!EasyUtils.isAppRunningForeground(appContext)) { EMLog.d(TAG, "app is running in backgroud"); sendNotification(messages, false); } else { sendNotification(messages, true); } vibrateAndPlayTone(messages.get(messages.size()-1)); } /** * send it to notification bar * 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); } /** * send it to notification bar * 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 title 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) { 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(); } } /** * vibrate and play tone */ public void vibrateAndPlayTone(EMMessage message) { if(message != null){ if(EMClient.getInstance().chatManager().isSlientMessage(message)){ return; } } if (System.currentTimeMillis() - lastNotifiyTime < 1000) { // received new messages within 2 seconds, skip play ringtone return; } try { lastNotifiyTime = System.currentTimeMillis(); // check if in silent mode if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) { EMLog.e(TAG, "in slient mode now"); return; } EaseSettingsProvider settingsProvider = EaseUI.getInstance().getSettingsProvider(); if(settingsProvider.isMsgVibrateAllowed(message)){ long[] pattern = new long[] { 0, 180, 80, 120 }; vibrator.vibrate(pattern, -1); } if(settingsProvider.isMsgSoundAllowed(message)){ 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(); } } /** * set notification info Provider * * @param provider */ public void setNotificationInfoProvider(EaseNotificationInfoProvider provider) { notificationInfoProvider = provider; } public interface EaseNotificationInfoProvider { /** * set the notification content, such as "you received a new image from xxx" * * @param message * @return null-will use the default text */ String getDisplayedText(EMMessage message); /** * set the notification content: such as "you received 5 message from 2 contacts" * * @param message * @param fromUsersNum- number of message sender * @param messageNum -number of messages * @return null-will use the default text */ String getLatestText(EMMessage message, int fromUsersNum, int messageNum); /** * 设置notification标题 * * @param message * @return null- will use the default text */ String getTitle(EMMessage message); /** * set the small icon * * @param message * @return 0- will use the default icon */ int getSmallIcon(EMMessage message); /** * set the intent when notification is pressed * * @param message * @return null- will use the default icon */ Intent getLaunchIntent(EMMessage message); } }