2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android
.support
.v4
.app
;
19 import android
.app
.Notification
;
20 import android
.app
.NotificationManager
;
21 import android
.app
.PendingIntent
;
22 import android
.content
.Context
;
23 import android
.graphics
.Bitmap
;
24 import android
.media
.AudioManager
;
25 import android
.net
.Uri
;
26 import android
.os
.Build
;
27 import android
.widget
.RemoteViews
;
28 import java
.util
.ArrayList
;
31 * Helper for accessing features in {@link android.app.Notification}
32 * introduced after API level 4 in a backwards compatible fashion.
34 public class NotificationCompat
{
36 * Obsolete flag indicating high-priority notifications; use the priority field instead.
38 * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value.
41 public static final int FLAG_HIGH_PRIORITY
= 0x00000080;
44 * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}.
45 * If your application does not prioritize its own notifications,
46 * use this value for all notifications.
48 public static final int PRIORITY_DEFAULT
= 0;
51 * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)},
52 * for items that are less important. The UI may choose to show
53 * these items smaller, or at a different position in the list,
54 * compared with your app's {@link #PRIORITY_DEFAULT} items.
56 public static final int PRIORITY_LOW
= -1;
59 * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)};
60 * these items might not be shown to the user except under
61 * special circumstances, such as detailed notification logs.
63 public static final int PRIORITY_MIN
= -2;
66 * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)},
67 * for more important notifications or alerts. The UI may choose
68 * to show these items larger, or at a different position in
69 * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items.
71 public static final int PRIORITY_HIGH
= 1;
74 * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)},
75 * for your application's most important items that require the user's
76 * prompt attention or input.
78 public static final int PRIORITY_MAX
= 2;
80 private static final NotificationCompatImpl IMPL
;
82 interface NotificationCompatImpl
{
83 public Notification
build(Builder b
);
86 static class NotificationCompatImplBase
implements NotificationCompatImpl
{
87 @SuppressWarnings("deprecation")
89 public Notification
build(Builder b
) {
90 Notification result
= b
.mNotification
;
91 result
.setLatestEventInfo(b
.mContext
, b
.mContentTitle
,
92 b
.mContentText
, b
.mContentIntent
);
93 // translate high priority requests into legacy flag
94 if (b
.mPriority
> PRIORITY_DEFAULT
) {
95 result
.flags
|= FLAG_HIGH_PRIORITY
;
101 static class NotificationCompatImplHoneycomb
implements NotificationCompatImpl
{
103 public Notification
build(Builder b
) {
104 return NotificationCompatHoneycomb
.add(b
.mContext
, b
.mNotification
,
105 b
.mContentTitle
, b
.mContentText
, b
.mContentInfo
, b
.mTickerView
,
106 b
.mNumber
, b
.mContentIntent
, b
.mFullScreenIntent
, b
.mLargeIcon
);
110 static class NotificationCompatImplIceCreamSandwich
implements NotificationCompatImpl
{
112 public Notification
build(Builder b
) {
113 return NotificationCompatIceCreamSandwich
.add(b
.mContext
, b
.mNotification
,
114 b
.mContentTitle
, b
.mContentText
, b
.mContentInfo
, b
.mTickerView
,
115 b
.mNumber
, b
.mContentIntent
, b
.mFullScreenIntent
, b
.mLargeIcon
,
116 b
.mProgressMax
, b
.mProgress
, b
.mProgressIndeterminate
);
120 static class NotificationCompatImplJellybean
implements NotificationCompatImpl
{
122 public Notification
build(Builder b
) {
123 NotificationCompatJellybean jbBuilder
= new NotificationCompatJellybean(
124 b
.mContext
, b
.mNotification
, b
.mContentTitle
, b
.mContentText
, b
.mContentInfo
,
125 b
.mTickerView
, b
.mNumber
, b
.mContentIntent
, b
.mFullScreenIntent
, b
.mLargeIcon
,
126 b
.mProgressMax
, b
.mProgress
, b
.mProgressIndeterminate
,
127 b
.mUseChronometer
, b
.mPriority
, b
.mSubText
);
128 for (Action action
: b
.mActions
) {
129 jbBuilder
.addAction(action
.icon
, action
.title
, action
.actionIntent
);
131 if (b
.mStyle
!= null) {
132 if (b
.mStyle
instanceof BigTextStyle
) {
133 BigTextStyle style
= (BigTextStyle
) b
.mStyle
;
134 jbBuilder
.addBigTextStyle(style
.mBigContentTitle
,
135 style
.mSummaryTextSet
,
138 } else if (b
.mStyle
instanceof InboxStyle
) {
139 InboxStyle style
= (InboxStyle
) b
.mStyle
;
140 jbBuilder
.addInboxStyle(style
.mBigContentTitle
,
141 style
.mSummaryTextSet
,
144 } else if (b
.mStyle
instanceof BigPictureStyle
) {
145 BigPictureStyle style
= (BigPictureStyle
) b
.mStyle
;
146 jbBuilder
.addBigPictureStyle(style
.mBigContentTitle
,
147 style
.mSummaryTextSet
,
152 return(jbBuilder
.build());
157 if (Build
.VERSION
.SDK_INT
>= 16) {
158 IMPL
= new NotificationCompatImplJellybean();
159 } else if (Build
.VERSION
.SDK_INT
>= 14) {
160 IMPL
= new NotificationCompatImplIceCreamSandwich();
161 } else if (Build
.VERSION
.SDK_INT
>= 11) {
162 IMPL
= new NotificationCompatImplHoneycomb();
164 IMPL
= new NotificationCompatImplBase();
169 * Builder class for {@link NotificationCompat} objects. Allows easier control over
170 * all the flags, as well as help constructing the typical notification layouts.
172 * On platform versions that don't offer expanded notifications, methods that depend on
173 * expanded notifications have no effect.
176 * For example, action buttons won't appear on platforms prior to Android 4.1. Action
177 * buttons depend on expanded notifications, which are only available in Android 4.1
180 * For this reason, you should always ensure that UI controls in a notification are also
181 * available in an {@link android.app.Activity} in your app, and you should always start that
182 * {@link android.app.Activity} when users click the notification. To do this, use the
183 * {@link NotificationCompat.Builder#setContentIntent setContentIntent()}
188 public static class Builder
{
191 CharSequence mContentTitle
;
192 CharSequence mContentText
;
193 PendingIntent mContentIntent
;
194 PendingIntent mFullScreenIntent
;
195 RemoteViews mTickerView
;
197 CharSequence mContentInfo
;
200 boolean mUseChronometer
;
202 CharSequence mSubText
;
205 boolean mProgressIndeterminate
;
206 ArrayList
<Action
> mActions
= new ArrayList
<Action
>();
208 Notification mNotification
= new Notification();
213 * Automatically sets the when field to {@link System#currentTimeMillis()
214 * System.currentTimeMillis()} and the audio stream to the
215 * {@link Notification#STREAM_DEFAULT}.
217 * @param context A {@link Context} that will be used to construct the
218 * RemoteViews. The Context will not be held past the lifetime of this
221 public Builder(Context context
) {
224 // Set defaults to match the defaults of a Notification
225 mNotification
.when
= System
.currentTimeMillis();
226 mNotification
.audioStreamType
= Notification
.STREAM_DEFAULT
;
227 mPriority
= PRIORITY_DEFAULT
;
231 * Set the time that the event occurred. Notifications in the panel are
232 * sorted by this time.
234 public Builder
setWhen(long when
) {
235 mNotification
.when
= when
;
240 * Show the {@link Notification#when} field as a stopwatch.
242 * Instead of presenting <code>when</code> as a timestamp, the notification will show an
243 * automatically updating display of the minutes and seconds since <code>when</code>.
245 * Useful when showing an elapsed time (like an ongoing phone call).
247 * @see android.widget.Chronometer
248 * @see Notification#when
250 public Builder
setUsesChronometer(boolean b
) {
256 * Set the small icon to use in the notification layouts. Different classes of devices
257 * may return different sizes. See the UX guidelines for more information on how to
258 * design these icons.
260 * @param icon A resource ID in the application's package of the drawble to use.
262 public Builder
setSmallIcon(int icon
) {
263 mNotification
.icon
= icon
;
268 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
269 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
270 * LevelListDrawable}.
272 * @param icon A resource ID in the application's package of the drawble to use.
273 * @param level The level to use for the icon.
275 * @see android.graphics.drawable.LevelListDrawable
277 public Builder
setSmallIcon(int icon
, int level
) {
278 mNotification
.icon
= icon
;
279 mNotification
.iconLevel
= level
;
284 * Set the title (first row) of the notification, in a standard notification.
286 public Builder
setContentTitle(CharSequence title
) {
287 mContentTitle
= title
;
292 * Set the text (second row) of the notification, in a standard notification.
294 public Builder
setContentText(CharSequence text
) {
300 * Set the third line of text in the platform notification template.
301 * Don't use if you're also using {@link #setProgress(int, int, boolean)};
302 * they occupy the same location in the standard template.
304 * If the platform does not provide large-format notifications, this method has no effect.
305 * The third line of text only appears in expanded view.
308 public Builder
setSubText(CharSequence text
) {
314 * Set the large number at the right-hand side of the notification. This is
315 * equivalent to setContentInfo, although it might show the number in a different
316 * font size for readability.
318 public Builder
setNumber(int number
) {
324 * Set the large text at the right-hand side of the notification.
326 public Builder
setContentInfo(CharSequence info
) {
332 * Set the progress this notification represents, which may be
333 * represented as a {@link android.widget.ProgressBar}.
335 public Builder
setProgress(int max
, int progress
, boolean indeterminate
) {
337 mProgress
= progress
;
338 mProgressIndeterminate
= indeterminate
;
343 * Supply a custom RemoteViews to use instead of the standard one.
345 public Builder
setContent(RemoteViews views
) {
346 mNotification
.contentView
= views
;
351 * Supply a {@link PendingIntent} to send when the notification is clicked.
352 * If you do not supply an intent, you can now add PendingIntents to individual
353 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
354 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to
355 * read {@link Notification#contentIntent Notification.contentIntent} for
356 * how to correctly use this.
358 public Builder
setContentIntent(PendingIntent intent
) {
359 mContentIntent
= intent
;
364 * Supply a {@link PendingIntent} to send when the notification is cleared by the user
365 * directly from the notification panel. For example, this intent is sent when the user
366 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
367 * intent is not sent when the application calls {@link NotificationManager#cancel
368 * NotificationManager.cancel(int)}.
370 public Builder
setDeleteIntent(PendingIntent intent
) {
371 mNotification
.deleteIntent
= intent
;
376 * An intent to launch instead of posting the notification to the status bar.
377 * Only for use with extremely high-priority notifications demanding the user's
378 * <strong>immediate</strong> attention, such as an incoming phone call or
379 * alarm clock that the user has explicitly set to a particular time.
380 * If this facility is used for something else, please give the user an option
381 * to turn it off and use a normal notification, as this can be extremely
384 * @param intent The pending intent to launch.
385 * @param highPriority Passing true will cause this notification to be sent
386 * even if other notifications are suppressed.
388 public Builder
setFullScreenIntent(PendingIntent intent
, boolean highPriority
) {
389 mFullScreenIntent
= intent
;
390 setFlag(FLAG_HIGH_PRIORITY
, highPriority
);
395 * Set the text that is displayed in the status bar when the notification first
398 public Builder
setTicker(CharSequence tickerText
) {
399 mNotification
.tickerText
= tickerText
;
404 * Set the text that is displayed in the status bar when the notification first
405 * arrives, and also a RemoteViews object that may be displayed instead on some
408 public Builder
setTicker(CharSequence tickerText
, RemoteViews views
) {
409 mNotification
.tickerText
= tickerText
;
415 * Set the large icon that is shown in the ticker and notification.
417 public Builder
setLargeIcon(Bitmap icon
) {
423 * Set the sound to play. It will play on the default stream.
425 public Builder
setSound(Uri sound
) {
426 mNotification
.sound
= sound
;
427 mNotification
.audioStreamType
= Notification
.STREAM_DEFAULT
;
432 * Set the sound to play. It will play on the stream you supply.
434 * @see #STREAM_DEFAULT
435 * @see AudioManager for the <code>STREAM_</code> constants.
437 public Builder
setSound(Uri sound
, int streamType
) {
438 mNotification
.sound
= sound
;
439 mNotification
.audioStreamType
= streamType
;
444 * Set the vibration pattern to use.
446 * @see android.os.Vibrator for a discussion of the <code>pattern</code>
449 public Builder
setVibrate(long[] pattern
) {
450 mNotification
.vibrate
= pattern
;
455 * Set the argb value that you would like the LED on the device to blnk, as well as the
456 * rate. The rate is specified in terms of the number of milliseconds to be on
457 * and then the number of milliseconds to be off.
459 public Builder
setLights(int argb
, int onMs
, int offMs
) {
460 mNotification
.ledARGB
= argb
;
461 mNotification
.ledOnMS
= onMs
;
462 mNotification
.ledOffMS
= offMs
;
463 boolean showLights
= mNotification
.ledOnMS
!= 0 && mNotification
.ledOffMS
!= 0;
464 mNotification
.flags
= (mNotification
.flags
& ~Notification
.FLAG_SHOW_LIGHTS
) |
465 (showLights ? Notification
.FLAG_SHOW_LIGHTS
: 0);
470 * Set whether this is an ongoing notification.
472 * <p>Ongoing notifications differ from regular notifications in the following ways:
474 * <li>Ongoing notifications are sorted above the regular notifications in the
475 * notification panel.</li>
476 * <li>Ongoing notifications do not have an 'X' close button, and are not affected
477 * by the "Clear all" button.
480 public Builder
setOngoing(boolean ongoing
) {
481 setFlag(Notification
.FLAG_ONGOING_EVENT
, ongoing
);
486 * Set this flag if you would only like the sound, vibrate
487 * and ticker to be played if the notification is not already showing.
489 public Builder
setOnlyAlertOnce(boolean onlyAlertOnce
) {
490 setFlag(Notification
.FLAG_ONLY_ALERT_ONCE
, onlyAlertOnce
);
495 * Setting this flag will make it so the notification is automatically
496 * canceled when the user clicks it in the panel. The PendingIntent
497 * set with {@link #setDeleteIntent} will be broadcast when the notification
500 public Builder
setAutoCancel(boolean autoCancel
) {
501 setFlag(Notification
.FLAG_AUTO_CANCEL
, autoCancel
);
506 * Set the default notification options that will be used.
508 * The value should be one or more of the following fields combined with
510 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE},
511 * {@link Notification#DEFAULT_LIGHTS}.
513 * For all default values, use {@link Notification#DEFAULT_ALL}.
515 public Builder
setDefaults(int defaults
) {
516 mNotification
.defaults
= defaults
;
517 if ((defaults
& Notification
.DEFAULT_LIGHTS
) != 0) {
518 mNotification
.flags
|= Notification
.FLAG_SHOW_LIGHTS
;
523 private void setFlag(int mask
, boolean value
) {
525 mNotification
.flags
|= mask
;
527 mNotification
.flags
&= ~mask
;
532 * Set the relative priority for this notification.
534 * Priority is an indication of how much of the user's
535 * valuable attention should be consumed by this
536 * notification. Low-priority notifications may be hidden from
537 * the user in certain situations, while the user might be
538 * interrupted for a higher-priority notification.
539 * The system sets a notification's priority based on various factors including the
540 * setPriority value. The effect may differ slightly on different platforms.
542 public Builder
setPriority(int pri
) {
548 * Add an action to this notification. Actions are typically displayed by
549 * the system as a button adjacent to the notification content.
551 * Action buttons won't appear on platforms prior to Android 4.1. Action
552 * buttons depend on expanded notifications, which are only available in Android 4.1
553 * and later. To ensure that an action button's functionality is always available, first
554 * implement the functionality in the {@link android.app.Activity} that starts when a user
555 * clicks the notification (see {@link #setContentIntent setContentIntent()}), and then
556 * enhance the notification by implementing the same functionality with
557 * {@link #addAction addAction()}.
559 * @param icon Resource ID of a drawable that represents the action.
560 * @param title Text describing the action.
561 * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked.
563 public Builder
addAction(int icon
, CharSequence title
, PendingIntent intent
) {
564 mActions
.add(new Action(icon
, title
, intent
));
569 * Add a rich notification style to be applied at build time.
571 * If the platform does not provide rich notification styles, this method has no effect. The
572 * user will always see the normal notification style.
574 * @param style Object responsible for modifying the notification style.
576 public Builder
setStyle(Style style
) {
577 if (mStyle
!= style
) {
579 if (mStyle
!= null) {
580 mStyle
.setBuilder(this);
587 * @deprecated Use {@link #build()} instead.
590 public Notification
getNotification() {
591 return IMPL
.build(this);
595 * Combine all of the options that have been set and return a new {@link Notification}
598 public Notification
build() {
599 return IMPL
.build(this);
604 * An object that can apply a rich notification style to a {@link Notification.Builder}
607 * If the platform does not provide rich notification styles, methods in this class have no
610 public static abstract class Style
613 CharSequence mBigContentTitle
;
614 CharSequence mSummaryText
;
615 boolean mSummaryTextSet
= false;
617 public void setBuilder(Builder builder
) {
618 if (mBuilder
!= builder
) {
620 if (mBuilder
!= null) {
621 mBuilder
.setStyle(this);
626 public Notification
build() {
627 Notification notification
= null;
628 if (mBuilder
!= null) {
629 notification
= mBuilder
.build();
636 * Helper class for generating large-format notifications that include a large image attachment.
638 * If the platform does not provide large-format notifications, this method has no effect. The
639 * user will always see the normal notification view.
641 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
642 * <pre class="prettyprint">
643 * Notification noti = new Notification.Builder()
644 * .setContentTitle("New photo from " + sender.toString())
645 * .setContentText(subject)
646 * .setSmallIcon(R.drawable.new_post)
647 * .setLargeIcon(aBitmap)
648 * .setStyle(new Notification.BigPictureStyle()
649 * .bigPicture(aBigBitmap))
653 * @see Notification#bigContentView
655 public static class BigPictureStyle
extends Style
{
658 public BigPictureStyle() {
661 public BigPictureStyle(Builder builder
) {
666 * Overrides ContentTitle in the big form of the template.
667 * This defaults to the value passed to setContentTitle().
669 public BigPictureStyle
setBigContentTitle(CharSequence title
) {
670 mBigContentTitle
= title
;
675 * Set the first line of text after the detail section in the big form of the template.
677 public BigPictureStyle
setSummaryText(CharSequence cs
) {
679 mSummaryTextSet
= true;
684 * Provide the bitmap to be used as the payload for the BigPicture notification.
686 public BigPictureStyle
bigPicture(Bitmap b
) {
693 * Helper class for generating large-format notifications that include a lot of text.
696 * If the platform does not provide large-format notifications, this method has no effect. The
697 * user will always see the normal notification view.
699 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
700 * <pre class="prettyprint">
701 * Notification noti = new Notification.Builder()
702 * .setContentTitle("New mail from " + sender.toString())
703 * .setContentText(subject)
704 * .setSmallIcon(R.drawable.new_mail)
705 * .setLargeIcon(aBitmap)
706 * .setStyle(new Notification.BigTextStyle()
707 * .bigText(aVeryLongString))
711 * @see Notification#bigContentView
713 public static class BigTextStyle
extends Style
{
714 CharSequence mBigText
;
716 public BigTextStyle() {
719 public BigTextStyle(Builder builder
) {
724 * Overrides ContentTitle in the big form of the template.
725 * This defaults to the value passed to setContentTitle().
727 public BigTextStyle
setBigContentTitle(CharSequence title
) {
728 mBigContentTitle
= title
;
733 * Set the first line of text after the detail section in the big form of the template.
735 public BigTextStyle
setSummaryText(CharSequence cs
) {
737 mSummaryTextSet
= true;
742 * Provide the longer text to be displayed in the big form of the
743 * template in place of the content text.
745 public BigTextStyle
bigText(CharSequence cs
) {
752 * Helper class for generating large-format notifications that include a list of (up to 5) strings.
755 * If the platform does not provide large-format notifications, this method has no effect. The
756 * user will always see the normal notification view.
758 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
759 * <pre class="prettyprint">
760 * Notification noti = new Notification.Builder()
761 * .setContentTitle("5 New mails from " + sender.toString())
762 * .setContentText(subject)
763 * .setSmallIcon(R.drawable.new_mail)
764 * .setLargeIcon(aBitmap)
765 * .setStyle(new Notification.InboxStyle()
768 * .setContentTitle("")
769 * .setSummaryText("+3 more"))
773 * @see Notification#bigContentView
775 public static class InboxStyle
extends Style
{
776 ArrayList
<CharSequence
> mTexts
= new ArrayList
<CharSequence
>();
778 public InboxStyle() {
781 public InboxStyle(Builder builder
) {
786 * Overrides ContentTitle in the big form of the template.
787 * This defaults to the value passed to setContentTitle().
789 public InboxStyle
setBigContentTitle(CharSequence title
) {
790 mBigContentTitle
= title
;
795 * Set the first line of text after the detail section in the big form of the template.
797 public InboxStyle
setSummaryText(CharSequence cs
) {
799 mSummaryTextSet
= true;
804 * Append a line to the digest section of the Inbox notification.
806 public InboxStyle
addLine(CharSequence cs
) {
812 public static class Action
{
814 public CharSequence title
;
815 public PendingIntent actionIntent
;
817 public Action(int icon_
, CharSequence title_
, PendingIntent intent_
) {
820 this.actionIntent
= intent_
;