From e1fa90b2fdebc4886a6a7927cf9cf1c6e433db1f Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 4 May 2012 22:03:35 +0200 Subject: [PATCH] Use Notification.Builder on Honeycomb+ devices Using the new helper class we can easily add support for some of the new notification features later. --- .../k9/controller/MessagingController.java | 221 ++++++++++++------ .../fsck/k9/helper/NotificationBuilder.java | 169 ++++++++++++++ .../k9/helper/NotificationBuilderApi1.java | 130 +++++++++++ .../k9/helper/NotificationBuilderApi11.java | 86 +++++++ 4 files changed, 529 insertions(+), 77 deletions(-) create mode 100644 src/com/fsck/k9/helper/NotificationBuilder.java create mode 100644 src/com/fsck/k9/helper/NotificationBuilderApi1.java create mode 100644 src/com/fsck/k9/helper/NotificationBuilderApi11.java diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 85442bfaf..942445d08 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -16,12 +16,10 @@ import java.util.concurrent.atomic.AtomicInteger; import android.app.Application; import android.app.KeyguardManager; -import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.media.AudioManager; import android.net.Uri; import android.os.PowerManager; import android.os.Process; @@ -38,6 +36,7 @@ import com.fsck.k9.SearchSpecification; import com.fsck.k9.K9.Intents; import com.fsck.k9.activity.FolderList; import com.fsck.k9.activity.MessageList; +import com.fsck.k9.helper.NotificationBuilder; import com.fsck.k9.helper.Utility; import com.fsck.k9.helper.power.TracingPowerManager; import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock; @@ -2997,80 +2996,139 @@ public class MessagingController implements Runnable { private void cancelNotification(int id) { NotificationManager notifMgr = - (NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE); + notifMgr.cancel(id); } private void notifyWhileSendingDone(Account account) { if (account.isShowOngoing()) { cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber()); - - } } + + /** + * Display an ongoing notification while a message is being sent. + * + * @param account + * The account the message is sent from. Never {@code null}. + */ private void notifyWhileSending(Account account) { if (!account.isShowOngoing()) { return; } + NotificationManager notifMgr = - (NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE); - Notification notif = new Notification(R.drawable.ic_menu_refresh, - mApplication.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis()); - Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName()); + (NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationBuilder builder = NotificationBuilder.getInstance(mApplication); + builder.setSmallIcon(R.drawable.ic_menu_refresh); + builder.setWhen(System.currentTimeMillis()); + builder.setOngoing(true); + builder.setTicker(mApplication.getString(R.string.notification_bg_send_ticker, + account.getDescription())); + + builder.setContentTitle(mApplication.getString(R.string.notification_bg_send_title)); + builder.setContentText(account.getDescription()); + + Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, + account.getInboxFolderName()); PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0); - notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_send_title), - account.getDescription() , pi); - notif.flags = Notification.FLAG_ONGOING_EVENT; + builder.setContentIntent(pi); if (K9.NOTIFICATION_LED_WHILE_SYNCING) { - configureNotification(notif, null, null, account.getNotificationSetting().getLedColor(), K9.NOTIFICATION_LED_BLINK_FAST, true); + configureNotification(builder, null, null, + account.getNotificationSetting().getLedColor(), + K9.NOTIFICATION_LED_BLINK_FAST, true); } - notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif); + notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), + builder.getNotification()); } private void notifySendTempFailed(Account account, Exception lastFailure) { notifySendFailed(account, lastFailure, account.getOutboxFolderName()); } + private void notifySendPermFailed(Account account, Exception lastFailure) { notifySendFailed(account, lastFailure, account.getDraftsFolderName()); } + + /** + * Display a notification when sending a message has failed. + * + * @param account + * The account that was used to sent the message. + * @param lastFailure + * The {@link Exception} instance that indicated sending the message has failed. + * @param openFolder + * The name of the folder to open when the notification is clicked. + */ private void notifySendFailed(Account account, Exception lastFailure, String openFolder) { - NotificationManager notifMgr = (NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE); - Notification notif = new Notification(R.drawable.stat_notify_email_generic, mApplication.getString(R.string.send_failure_subject), System.currentTimeMillis()); + NotificationManager notifMgr = + (NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationBuilder builder = NotificationBuilder.getInstance(mApplication); + builder.setSmallIcon(R.drawable.stat_notify_email_generic); + builder.setWhen(System.currentTimeMillis()); + builder.setAutoCancel(true); + builder.setTicker(mApplication.getString(R.string.send_failure_subject)); + builder.setContentTitle(mApplication.getString(R.string.send_failure_subject)); + builder.setContentText(getRootCauseMessage(lastFailure)); Intent i = FolderList.actionHandleNotification(mApplication, account, openFolder); - PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0); + builder.setContentIntent(pi); - notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.send_failure_subject), getRootCauseMessage(lastFailure), pi); + configureNotification(builder, null, null, K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR, + K9.NOTIFICATION_LED_BLINK_FAST, true); - configureNotification(notif, null, null, K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR, K9.NOTIFICATION_LED_BLINK_FAST, true); - notif.flags |= Notification.FLAG_AUTO_CANCEL; - notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(), notif); + notifMgr.notify(K9.SEND_FAILED_NOTIFICATION - account.getAccountNumber(), + builder.getNotification()); } - + /** + * Display an ongoing notification while checking for new messages on the server. + * + * @param account + * The account that is checked for new messages. Never {@code null}. + * @param folder + * The folder that is being checked for new messages. Never {@code null}. + */ private void notifyFetchingMail(final Account account, final Folder folder) { - if (account.isShowOngoing()) { - final NotificationManager notifMgr = (NotificationManager)mApplication - .getSystemService(Context.NOTIFICATION_SERVICE); - Notification notif = new Notification(R.drawable.ic_menu_refresh, - mApplication.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()), - System.currentTimeMillis()); - Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, account.getInboxFolderName()); - PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0); - notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.notification_bg_sync_title), account.getDescription() - + mApplication.getString(R.string.notification_bg_title_separator) + folder.getName(), pi); - notif.flags = Notification.FLAG_ONGOING_EVENT; - - if (K9.NOTIFICATION_LED_WHILE_SYNCING) { - configureNotification(notif, null, null, account.getNotificationSetting().getLedColor(), K9.NOTIFICATION_LED_BLINK_FAST, true); - } - - notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif); + if (!account.isShowOngoing()) { + return; } + + final NotificationManager notifMgr = + (NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationBuilder builder = NotificationBuilder.getInstance(mApplication); + builder.setSmallIcon(R.drawable.ic_menu_refresh); + builder.setWhen(System.currentTimeMillis()); + builder.setOngoing(true); + builder.setTicker(mApplication.getString( + R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName())); + builder.setContentTitle(mApplication.getString(R.string.notification_bg_sync_title)); + builder.setContentText(account.getDescription() + + mApplication.getString(R.string.notification_bg_title_separator) + + folder.getName()); + + Intent intent = MessageList.actionHandleFolderIntent(mApplication, account, + account.getInboxFolderName()); + PendingIntent pi = PendingIntent.getActivity(mApplication, 0, intent, 0); + builder.setContentIntent(pi); + + if (K9.NOTIFICATION_LED_WHILE_SYNCING) { + configureNotification(builder, null, null, + account.getNotificationSetting().getLedColor(), + K9.NOTIFICATION_LED_BLINK_FAST, true); + } + + notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), + builder.getNotification()); } + private void notifyFetchingMailCancel(final Account account) { if (account.isShowOngoing()) { cancelNotification(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber()); @@ -4126,22 +4184,31 @@ public class MessagingController implements Runnable { } NotificationManager notifMgr = - (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); - Notification notif = new Notification(R.drawable.stat_notify_email_generic, messageNotice, System.currentTimeMillis()); + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + + NotificationBuilder builder = NotificationBuilder.getInstance(context); + builder.setSmallIcon(R.drawable.stat_notify_email_generic); + builder.setWhen(System.currentTimeMillis()); + builder.setTicker(messageNotice); + final int unreadCount = previousUnreadMessageCount + newMessageCount.get(); if (account.isNotificationShowsUnreadCount()) { - notif.number = unreadCount; + builder.setNumber(unreadCount); } - Intent i = FolderList.actionHandleNotification(context, account, message.getFolder().getName()); + String accountDescr = (account.getDescription() != null) ? + account.getDescription() : account.getEmail(); + String accountNotice = context.getString(R.string.notification_new_one_account_fmt, + unreadCount, accountDescr); + builder.setContentTitle(accountNotice); + builder.setContentText(messageNotice); + + Intent i = FolderList.actionHandleNotification(context, account, + message.getFolder().getName()); PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0); + builder.setContentIntent(pi); - String accountDescr = (account.getDescription() != null) ? account.getDescription() : account.getEmail(); - String accountNotice = context.getString(R.string.notification_new_one_account_fmt, unreadCount, accountDescr); - notif.setLatestEventInfo(context, accountNotice, messageNotice, pi); - - // Only ring or vibrate if we have not done so already on this - // account and fetch + // Only ring or vibrate if we have not done so already on this account and fetch boolean ringAndVibrate = false; if (!account.isRingNotified()) { account.setRingNotified(true); @@ -4151,38 +4218,36 @@ public class MessagingController implements Runnable { NotificationSetting n = account.getNotificationSetting(); configureNotification( - notif, + builder, (n.shouldRing()) ? n.getRingtone() : null, (n.shouldVibrate()) ? n.getVibration() : null, (n.isLed()) ? Integer.valueOf(n.getLedColor()) : null, K9.NOTIFICATION_LED_BLINK_SLOW, ringAndVibrate); - notifMgr.notify(account.getAccountNumber(), notif); + notifMgr.notify(account.getAccountNumber(), builder.getNotification()); } /** - * @param notification - * Object to configure. Never null. + * Configure the notification sound and LED + * + * @param builder + * {@link NotificationBuilder} instance used to configure the notification. + * Never {@code null}. * @param ringtone - * String name of ringtone. null if no ringtone should be played + * String name of ringtone. {@code null}, if no ringtone should be played. * @param vibrationPattern - * long[] vibration pattern. null if no vibration should be played + * {@code long[]} vibration pattern. {@code null}, if no vibration should be played. * @param ledColor - * Integer Color to flash LED. null if no LED flash should happen + * Color to flash LED. {@code null}, if no LED flash should happen. * @param ledSpeed - * int should LEDs flash K9.NOTIFICATION_LED_BLINK_SLOW or K9.NOTIFICATION_LED_BLINK_FAST + * Either {@link K9#NOTIFICATION_LED_BLINK_SLOW} or + * {@link K9#NOTIFICATION_LED_BLINK_FAST}. * @param ringAndVibrate - * true if ringtone/vibration are allowed, - * false otherwise. + * {@code true}, if ringtone/vibration are allowed. {@code false}, otherwise. */ - private void configureNotification(final Notification notification, - final String ringtone, - final long[] vibrationPattern, - final Integer ledColor, - final int ledSpeed, - - final boolean ringAndVibrate) { + private void configureNotification(NotificationBuilder builder, String ringtone, + long[] vibrationPattern, Integer ledColor, int ledSpeed, boolean ringAndVibrate) { // if it's quiet time, then we shouldn't be ringing, buzzing or flashing if (K9.isQuietTime()) { @@ -4190,25 +4255,27 @@ public class MessagingController implements Runnable { } if (ringAndVibrate) { - if (ringtone != null) { - notification.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone); - notification.audioStreamType = AudioManager.STREAM_NOTIFICATION; + if (ringtone != null && !TextUtils.isEmpty(ringtone)) { + builder.setSound(Uri.parse(ringtone)); } + if (vibrationPattern != null) { - notification.vibrate = vibrationPattern; + builder.setVibrate(vibrationPattern); } } if (ledColor != null) { - notification.flags |= Notification.FLAG_SHOW_LIGHTS; - notification.ledARGB = ledColor; + int ledOnMS; + int ledOffMS; if (ledSpeed == K9.NOTIFICATION_LED_BLINK_SLOW) { - notification.ledOnMS = K9.NOTIFICATION_LED_ON_TIME; - notification.ledOffMS = K9.NOTIFICATION_LED_OFF_TIME; - } else if (ledSpeed == K9.NOTIFICATION_LED_BLINK_FAST) { - notification.ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME; - notification.ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME; + ledOnMS = K9.NOTIFICATION_LED_ON_TIME; + ledOffMS = K9.NOTIFICATION_LED_OFF_TIME; + } else { + ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME; + ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME; } + + builder.setLights(ledColor, ledOnMS, ledOffMS); } } diff --git a/src/com/fsck/k9/helper/NotificationBuilder.java b/src/com/fsck/k9/helper/NotificationBuilder.java new file mode 100644 index 000000000..df052c218 --- /dev/null +++ b/src/com/fsck/k9/helper/NotificationBuilder.java @@ -0,0 +1,169 @@ +package com.fsck.k9.helper; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.net.Uri; +import android.os.Build; +import android.os.Vibrator; + +/** + * Helper class to create system notifications + * + * @see NotificationBuilderApi1 + * @see NotificationBuilderApi11 + */ +public abstract class NotificationBuilder { + /** + * Instance of the API-specific class that is used to create system notifications + */ + private static NotificationBuilder sInstance = null; + + /** + * Get API-specific instance of the {@code NotificationBuilder} class + * + * @param context + * A {@link Context} instance. + * + * @return Appropriate {@link NotificationBuilder} instance for this device. + */ + public static NotificationBuilder getInstance(Context context) { + Context appContext = context.getApplicationContext(); + + if (sInstance == null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + sInstance = new NotificationBuilderApi1(appContext); + } else { + sInstance = new NotificationBuilderApi11(appContext); + } + } + + return sInstance; + } + + + protected Context mContext; + + /** + * Constructor + * + * @param context + * A {@link Context} instance. + */ + protected NotificationBuilder(Context context) { + mContext = context; + } + + /** + * Set the small icon to use in the notification layouts. + * + * @param icon + * A resource ID in the application's package of the drawble to use. + */ + public abstract void setSmallIcon(int icon); + + /** + * Set the time that the event occurred. + * + * @param when + * Timestamp of when the event occurred. + */ + public abstract void setWhen(long when); + + /** + * Set the text that is displayed in the status bar when the notification first arrives. + * + * @param tickerText + * The text to display. + */ + public abstract void setTicker(CharSequence tickerText); + + /** + * Set the title (first row) of the notification, in a standard notification. + * + * @param title + * The text to display as notification title. + */ + public abstract void setContentTitle(CharSequence title); + + /** + * Set the text (second row) of the notification, in a standard notification. + * + * @param text + * The text to display. + */ + public abstract void setContentText(CharSequence text); + + /** + * Supply a PendingIntent to send when the notification is clicked. + * + * @param intent + * The intent that will be sent when the notification was clicked. + */ + public abstract void setContentIntent(PendingIntent intent); + + /** + * Set the large number at the right-hand side of the notification. + * + * @param number + * The number to display in the notification. + */ + public abstract void setNumber(int number); + + /** + * Set whether this is an ongoing notification. + * + * @param ongoing + * {@code true}, if it this is an ongoing notification. {@code false}, otherwise. + */ + public abstract void setOngoing(boolean ongoing); + + /** + * Setting this flag will make it so the notification is automatically canceled when the user + * clicks it in the panel. + * + * @param autoCancel + * {@code true}, if the notification should be automatically cancelled when the user + * clicks on it. {@code false}, otherwise. + */ + public abstract void setAutoCancel(boolean autoCancel); + + /** + * Set the sound to play. + * + * It will play on the notification stream. + * + * @param sound + * The URI of the sound to play. + */ + public abstract void setSound(Uri sound); + + /** + * Set the vibration pattern to use. + * + * @param pattern + * An array of longs of times for which to turn the vibrator on or off. + * + * @see Vibrator#vibrate(long[], int) + */ + public abstract void setVibrate(long[] pattern); + + /** + * Set the color that you would like the LED on the device to blink, as well as the rate. + * + * @param argb + * The color the LED should blink. + * @param onMs + * The number of milliseconds the LED should be on. + * @param offMs + * The number of milliseconds the LED should be off. + */ + public abstract void setLights(int argb, int onMs, int offMs); + + /** + * Combine all of the options that have been set and return a new {@link Notification} object. + * + * @return A new {@code Notification} object configured by this {@link NotificationBuilder}. + */ + public abstract Notification getNotification(); +} diff --git a/src/com/fsck/k9/helper/NotificationBuilderApi1.java b/src/com/fsck/k9/helper/NotificationBuilderApi1.java new file mode 100644 index 000000000..c57a77991 --- /dev/null +++ b/src/com/fsck/k9/helper/NotificationBuilderApi1.java @@ -0,0 +1,130 @@ +package com.fsck.k9.helper; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.media.AudioManager; +import android.net.Uri; + +/** + * Create notifications using the now deprecated {@link Notification} constructor. + */ +public class NotificationBuilderApi1 extends NotificationBuilder { + private int mSmallIcon; + private long mWhen; + private CharSequence mTickerText; + private CharSequence mContentText; + private CharSequence mContentTitle; + private PendingIntent mContentIntent; + private int mNumber; + private boolean mOngoing; + private boolean mAutoCancel; + private Uri mSoundUri; + private long[] mVibrationPattern; + private int mLedColor; + private int mLedOnMS; + private int mLedOffMS; + private boolean mBlinkLed; + + + protected NotificationBuilderApi1(Context context) { + super(context); + } + + @Override + public void setSmallIcon(int icon) { + mSmallIcon = icon; + } + + @Override + public void setWhen(long when) { + mWhen = when; + } + + @Override + public void setTicker(CharSequence tickerText) { + mTickerText = tickerText; + } + + @Override + public void setContentTitle(CharSequence title) { + mContentTitle = title; + } + + @Override + public void setContentText(CharSequence text) { + mContentText = text; + } + + @Override + public void setContentIntent(PendingIntent intent) { + mContentIntent = intent; + } + + @Override + public void setNumber(int number) { + mNumber = number; + } + + @Override + public void setOngoing(boolean ongoing) { + mOngoing = ongoing; + } + + @Override + public void setAutoCancel(boolean autoCancel) { + mAutoCancel = autoCancel; + } + + @Override + public void setSound(Uri sound) { + mSoundUri = sound; + } + + @Override + public void setVibrate(long[] pattern) { + mVibrationPattern = pattern; + } + + @Override + public void setLights(int argb, int onMs, int offMs) { + mBlinkLed = true; + mLedColor = argb; + mLedOnMS = onMs; + mLedOffMS = offMs; + } + + @SuppressWarnings("deprecation") + @Override + public Notification getNotification() { + Notification notification = new Notification(mSmallIcon, mTickerText, mWhen); + notification.number = mNumber; + notification.setLatestEventInfo(mContext, mContentTitle, mContentText, mContentIntent); + + if (mSoundUri != null) { + notification.sound = mSoundUri; + notification.audioStreamType = AudioManager.STREAM_NOTIFICATION; + } + + if (mVibrationPattern != null) { + notification.vibrate = mVibrationPattern; + } + + if (mBlinkLed) { + notification.flags |= Notification.FLAG_SHOW_LIGHTS; + notification.ledARGB = mLedColor; + notification.ledOnMS = mLedOnMS; + notification.ledOffMS = mLedOffMS; + } + + if (mAutoCancel) { + notification.flags |= Notification.FLAG_AUTO_CANCEL; + } + + if (mOngoing) { + notification.flags |= Notification.FLAG_ONGOING_EVENT; + } + + return notification; + } +} diff --git a/src/com/fsck/k9/helper/NotificationBuilderApi11.java b/src/com/fsck/k9/helper/NotificationBuilderApi11.java new file mode 100644 index 000000000..fc9772b7d --- /dev/null +++ b/src/com/fsck/k9/helper/NotificationBuilderApi11.java @@ -0,0 +1,86 @@ +package com.fsck.k9.helper; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.media.AudioManager; +import android.net.Uri; + +/** + * Create notifications using the new {@link android.app.Notification.Builder} class. + */ +public class NotificationBuilderApi11 extends NotificationBuilder { + private Notification.Builder mBuilder; + + + protected NotificationBuilderApi11(Context context) { + super(context); + mBuilder = new Notification.Builder(context); + } + + @Override + public void setSmallIcon(int icon) { + mBuilder.setSmallIcon(icon); + } + + @Override + public void setWhen(long when) { + mBuilder.setWhen(when); + } + + @Override + public void setTicker(CharSequence tickerText) { + mBuilder.setTicker(tickerText); + } + + @Override + public void setContentTitle(CharSequence title) { + mBuilder.setContentTitle(title); + } + + @Override + public void setContentText(CharSequence text) { + mBuilder.setContentText(text); + } + + @Override + public void setContentIntent(PendingIntent intent) { + mBuilder.setContentIntent(intent); + } + + @Override + public void setNumber(int number) { + mBuilder.setNumber(number); + mBuilder.setContentInfo("" + number); + } + + @Override + public void setOngoing(boolean ongoing) { + mBuilder.setOngoing(ongoing); + } + + @Override + public void setAutoCancel(boolean autoCancel) { + mBuilder.setAutoCancel(autoCancel); + } + + @Override + public void setSound(Uri sound) { + mBuilder.setSound(sound, AudioManager.STREAM_NOTIFICATION); + } + + @Override + public void setVibrate(long[] pattern) { + mBuilder.setVibrate(pattern); + } + + @Override + public void setLights(int argb, int onMs, int offMs) { + mBuilder.setLights(argb, onMs, offMs); + } + + @Override + public Notification getNotification() { + return mBuilder.getNotification(); + } +}