NotificationCompat.java revision 49714d665f839c4804a17eea129092f8b472926d
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package android.support.v4.app;
18
19import android.app.Notification;
20import android.app.NotificationManager;
21import android.app.PendingIntent;
22import android.content.Context;
23import android.graphics.Bitmap;
24import android.media.AudioManager;
25import android.net.Uri;
26import android.os.Build;
27import android.widget.RemoteViews;
28import java.util.ArrayList;
29
30/**
31 * Helper for accessing features in {@link android.app.Notification}
32 * introduced after API level 4 in a backwards compatible fashion.
33 */
34public class NotificationCompat {
35    /**
36     * Obsolete flag indicating high-priority notifications; use the priority field instead.
37     *
38     * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value.
39     */
40    public static final int FLAG_HIGH_PRIORITY = 0x00000080;
41
42    /**
43     * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}.
44     * If your application does not prioritize its own notifications,
45     * use this value for all notifications.
46     */
47    public static final int PRIORITY_DEFAULT = 0;
48
49    /**
50     * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)},
51     * for items that are less important. The UI may choose to show
52     * these items smaller, or at a different position in the list,
53     * compared with your app's {@link #PRIORITY_DEFAULT} items.
54     */
55    public static final int PRIORITY_LOW = -1;
56
57    /**
58     * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)};
59     * these items might not be shown to the user except under
60     * special circumstances, such as detailed notification logs.
61     */
62    public static final int PRIORITY_MIN = -2;
63
64    /**
65     * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)},
66     * for more important notifications or alerts. The UI may choose
67     * to show these items larger, or at a different position in
68     * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items.
69     */
70    public static final int PRIORITY_HIGH = 1;
71
72    /**
73     * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)},
74     * for your application's most important items that require the user's
75     * prompt attention or input.
76     */
77    public static final int PRIORITY_MAX = 2;
78
79    private static final NotificationCompatImpl IMPL;
80
81    interface NotificationCompatImpl {
82        public Notification build(Builder b);
83    }
84
85    static class NotificationCompatImplBase implements NotificationCompatImpl {
86        public Notification build(Builder b) {
87            Notification result = (Notification) b.mNotification;
88            result.setLatestEventInfo(b.mContext, b.mContentTitle,
89                    b.mContentText, b.mContentIntent);
90            // translate high priority requests into legacy flag
91            if (b.mPriority > PRIORITY_DEFAULT) {
92                result.flags |= FLAG_HIGH_PRIORITY;
93            }
94            return result;
95        }
96    }
97
98    static class NotificationCompatImplHoneycomb implements NotificationCompatImpl {
99        public Notification build(Builder b) {
100            return NotificationCompatHoneycomb.add(b.mContext, b.mNotification,
101                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
102                    b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon);
103        }
104    }
105
106    static class NotificationCompatImplIceCreamSandwich implements NotificationCompatImpl {
107        public Notification build(Builder b) {
108            return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification,
109                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
110                    b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
111                    b.mProgressMax, b.mProgress, b.mProgressIndeterminate);
112        }
113    }
114
115    static class NotificationCompatImplJellybean implements NotificationCompatImpl {
116        public Notification build(Builder b) {
117            NotificationCompatJellybean jbBuilder = new NotificationCompatJellybean(
118                    b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
119                    b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
120                    b.mProgressMax, b.mProgress, b.mProgressIndeterminate,
121                    b.mUseChronometer, b.mPriority, b.mSubText);
122            for (Action action: b.mActions) {
123                jbBuilder.addAction(action.icon, action.title, action.actionIntent);
124            }
125            if (b.mStyle != null) {
126                if (b.mStyle instanceof BigTextStyle) {
127                    BigTextStyle style = (BigTextStyle) b.mStyle;
128                    jbBuilder.addBigTextStyle(style.mBigContentTitle,
129                            style.mSummaryTextSet,
130                            style.mSummaryText,
131                            style.mBigText);
132                } else if (b.mStyle instanceof InboxStyle) {
133                    InboxStyle style = (InboxStyle) b.mStyle;
134                    jbBuilder.addInboxStyle(style.mBigContentTitle,
135                            style.mSummaryTextSet,
136                            style.mSummaryText,
137                            style.mTexts);
138                } else if (b.mStyle instanceof BigPictureStyle) {
139                    BigPictureStyle style = (BigPictureStyle) b.mStyle;
140                    jbBuilder.addBigPictureStyle(style.mBigContentTitle,
141                            style.mSummaryTextSet,
142                            style.mSummaryText,
143                            style.mPicture,
144                            style.mBigLargeIcon,
145                            style.mBigLargeIconSet);
146                }
147            }
148            return(jbBuilder.build());
149        }
150    }
151
152    static {
153        if (Build.VERSION.SDK_INT >= 16) {
154            IMPL = new NotificationCompatImplJellybean();
155        } else if (Build.VERSION.SDK_INT >= 14) {
156            IMPL = new NotificationCompatImplIceCreamSandwich();
157        } else if (Build.VERSION.SDK_INT >= 11) {
158            IMPL = new NotificationCompatImplHoneycomb();
159        } else {
160            IMPL = new NotificationCompatImplBase();
161        }
162    }
163
164    /**
165     * Builder class for {@link NotificationCompat} objects.  Allows easier control over
166     * all the flags, as well as help constructing the typical notification layouts.
167     * <p>
168     * On platform versions that don't offer expanded notifications, methods that depend on
169     * expanded notifications have no effect.
170     * </p>
171     * <p>
172     * For example, action buttons won't appear on platforms prior to Android 4.1. Action
173     * buttons depend on expanded notifications, which are only available in Android 4.1
174     * and later.
175     * <p>
176     * For this reason, you should always ensure that UI controls in a notification are also
177     * available in an {@link android.app.Activity} in your app, and you should always start that
178     * {@link android.app.Activity} when users click the notification. To do this, use the
179     * {@link NotificationCompat.Builder#setContentIntent setContentIntent()}
180     * method.
181     * </p>
182     *
183     */
184    public static class Builder {
185        Context mContext;
186
187        CharSequence mContentTitle;
188        CharSequence mContentText;
189        PendingIntent mContentIntent;
190        PendingIntent mFullScreenIntent;
191        RemoteViews mTickerView;
192        Bitmap mLargeIcon;
193        CharSequence mContentInfo;
194        int mNumber;
195        int mPriority;
196        boolean mUseChronometer;
197        Style mStyle;
198        CharSequence mSubText;
199        int mProgressMax;
200        int mProgress;
201        boolean mProgressIndeterminate;
202        ArrayList<Action> mActions = new ArrayList<Action>();
203
204        Notification mNotification = new Notification();
205
206        /**
207         * Constructor.
208         *
209         * Automatically sets the when field to {@link System#currentTimeMillis()
210         * System.currentTimeMillis()} and the audio stream to the
211         * {@link Notification#STREAM_DEFAULT}.
212         *
213         * @param context A {@link Context} that will be used to construct the
214         *      RemoteViews. The Context will not be held past the lifetime of this
215         *      Builder object.
216         */
217        public Builder(Context context) {
218            mContext = context;
219
220            // Set defaults to match the defaults of a Notification
221            mNotification.when = System.currentTimeMillis();
222            mNotification.audioStreamType = Notification.STREAM_DEFAULT;
223            mPriority = PRIORITY_DEFAULT;
224        }
225
226        /**
227         * Set the time that the event occurred.  Notifications in the panel are
228         * sorted by this time.
229         */
230        public Builder setWhen(long when) {
231            mNotification.when = when;
232            return this;
233        }
234
235        /**
236         * Show the {@link Notification#when} field as a stopwatch.
237         *
238         * Instead of presenting <code>when</code> as a timestamp, the notification will show an
239         * automatically updating display of the minutes and seconds since <code>when</code>.
240         *
241         * Useful when showing an elapsed time (like an ongoing phone call).
242         *
243         * @see android.widget.Chronometer
244         * @see Notification#when
245         */
246        public Builder setUsesChronometer(boolean b) {
247            mUseChronometer = b;
248            return this;
249        }
250
251        /**
252         * Set the small icon to use in the notification layouts.  Different classes of devices
253         * may return different sizes.  See the UX guidelines for more information on how to
254         * design these icons.
255         *
256         * @param icon A resource ID in the application's package of the drawble to use.
257         */
258        public Builder setSmallIcon(int icon) {
259            mNotification.icon = icon;
260            return this;
261        }
262
263        /**
264         * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
265         * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
266         * LevelListDrawable}.
267         *
268         * @param icon A resource ID in the application's package of the drawble to use.
269         * @param level The level to use for the icon.
270         *
271         * @see android.graphics.drawable.LevelListDrawable
272         */
273        public Builder setSmallIcon(int icon, int level) {
274            mNotification.icon = icon;
275            mNotification.iconLevel = level;
276            return this;
277        }
278
279        /**
280         * Set the title (first row) of the notification, in a standard notification.
281         */
282        public Builder setContentTitle(CharSequence title) {
283            mContentTitle = title;
284            return this;
285        }
286
287        /**
288         * Set the text (second row) of the notification, in a standard notification.
289         */
290        public Builder setContentText(CharSequence text) {
291            mContentText = text;
292            return this;
293        }
294
295        /**
296         * Set the third line of text in the platform notification template.
297         * Don't use if you're also using {@link #setProgress(int, int, boolean)};
298         * they occupy the same location in the standard template.
299         * <br>
300         * If the platform does not provide large-format notifications, this method has no effect.
301         * The third line of text only appears in expanded view.
302         * <br>
303         */
304        public Builder setSubText(CharSequence text) {
305            mSubText = text;
306            return this;
307        }
308
309        /**
310         * Set the large number at the right-hand side of the notification.  This is
311         * equivalent to setContentInfo, although it might show the number in a different
312         * font size for readability.
313         */
314        public Builder setNumber(int number) {
315            mNumber = number;
316            return this;
317        }
318
319        /**
320         * Set the large text at the right-hand side of the notification.
321         */
322        public Builder setContentInfo(CharSequence info) {
323            mContentInfo = info;
324            return this;
325        }
326
327        /**
328         * Set the progress this notification represents, which may be
329         * represented as a {@link android.widget.ProgressBar}.
330         */
331        public Builder setProgress(int max, int progress, boolean indeterminate) {
332            mProgressMax = max;
333            mProgress = progress;
334            mProgressIndeterminate = indeterminate;
335            return this;
336        }
337
338        /**
339         * Supply a custom RemoteViews to use instead of the standard one.
340         */
341        public Builder setContent(RemoteViews views) {
342            mNotification.contentView = views;
343            return this;
344        }
345
346        /**
347         * Supply a {@link PendingIntent} to send when the notification is clicked.
348         * If you do not supply an intent, you can now add PendingIntents to individual
349         * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
350         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.  Be sure to
351         * read {@link Notification#contentIntent Notification.contentIntent} for
352         * how to correctly use this.
353         */
354        public Builder setContentIntent(PendingIntent intent) {
355            mContentIntent = intent;
356            return this;
357        }
358
359        /**
360         * Supply a {@link PendingIntent} to send when the notification is cleared by the user
361         * directly from the notification panel.  For example, this intent is sent when the user
362         * clicks the "Clear all" button, or the individual "X" buttons on notifications.  This
363         * intent is not sent when the application calls {@link NotificationManager#cancel
364         * NotificationManager.cancel(int)}.
365         */
366        public Builder setDeleteIntent(PendingIntent intent) {
367            mNotification.deleteIntent = intent;
368            return this;
369        }
370
371        /**
372         * An intent to launch instead of posting the notification to the status bar.
373         * Only for use with extremely high-priority notifications demanding the user's
374         * <strong>immediate</strong> attention, such as an incoming phone call or
375         * alarm clock that the user has explicitly set to a particular time.
376         * If this facility is used for something else, please give the user an option
377         * to turn it off and use a normal notification, as this can be extremely
378         * disruptive.
379         *
380         * @param intent The pending intent to launch.
381         * @param highPriority Passing true will cause this notification to be sent
382         *          even if other notifications are suppressed.
383         */
384        public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
385            mFullScreenIntent = intent;
386            setFlag(FLAG_HIGH_PRIORITY, highPriority);
387            return this;
388        }
389
390        /**
391         * Set the text that is displayed in the status bar when the notification first
392         * arrives.
393         */
394        public Builder setTicker(CharSequence tickerText) {
395            mNotification.tickerText = tickerText;
396            return this;
397        }
398
399        /**
400         * Set the text that is displayed in the status bar when the notification first
401         * arrives, and also a RemoteViews object that may be displayed instead on some
402         * devices.
403         */
404        public Builder setTicker(CharSequence tickerText, RemoteViews views) {
405            mNotification.tickerText = tickerText;
406            mTickerView = views;
407            return this;
408        }
409
410        /**
411         * Set the large icon that is shown in the ticker and notification.
412         */
413        public Builder setLargeIcon(Bitmap icon) {
414            mLargeIcon = icon;
415            return this;
416        }
417
418        /**
419         * Set the sound to play.  It will play on the default stream.
420         */
421        public Builder setSound(Uri sound) {
422            mNotification.sound = sound;
423            mNotification.audioStreamType = Notification.STREAM_DEFAULT;
424            return this;
425        }
426
427        /**
428         * Set the sound to play.  It will play on the stream you supply.
429         *
430         * @see #STREAM_DEFAULT
431         * @see AudioManager for the <code>STREAM_</code> constants.
432         */
433        public Builder setSound(Uri sound, int streamType) {
434            mNotification.sound = sound;
435            mNotification.audioStreamType = streamType;
436            return this;
437        }
438
439        /**
440         * Set the vibration pattern to use.
441         *
442         * @see android.os.Vibrator for a discussion of the <code>pattern</code>
443         * parameter.
444         */
445        public Builder setVibrate(long[] pattern) {
446            mNotification.vibrate = pattern;
447            return this;
448        }
449
450        /**
451         * Set the argb value that you would like the LED on the device to blnk, as well as the
452         * rate.  The rate is specified in terms of the number of milliseconds to be on
453         * and then the number of milliseconds to be off.
454         */
455        public Builder setLights(int argb, int onMs, int offMs) {
456            mNotification.ledARGB = argb;
457            mNotification.ledOnMS = onMs;
458            mNotification.ledOffMS = offMs;
459            boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0;
460            mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) |
461                    (showLights ? Notification.FLAG_SHOW_LIGHTS : 0);
462            return this;
463        }
464
465        /**
466         * Set whether this is an ongoing notification.
467         *
468         * <p>Ongoing notifications differ from regular notifications in the following ways:
469         * <ul>
470         *   <li>Ongoing notifications are sorted above the regular notifications in the
471         *   notification panel.</li>
472         *   <li>Ongoing notifications do not have an 'X' close button, and are not affected
473         *   by the "Clear all" button.
474         * </ul>
475         */
476        public Builder setOngoing(boolean ongoing) {
477            setFlag(Notification.FLAG_ONGOING_EVENT, ongoing);
478            return this;
479        }
480
481        /**
482         * Set this flag if you would only like the sound, vibrate
483         * and ticker to be played if the notification is not already showing.
484         */
485        public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
486            setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
487            return this;
488        }
489
490        /**
491         * Setting this flag will make it so the notification is automatically
492         * canceled when the user clicks it in the panel.  The PendingIntent
493         * set with {@link #setDeleteIntent} will be broadcast when the notification
494         * is canceled.
495         */
496        public Builder setAutoCancel(boolean autoCancel) {
497            setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel);
498            return this;
499        }
500
501        /**
502         * Set the default notification options that will be used.
503         * <p>
504         * The value should be one or more of the following fields combined with
505         * bitwise-or:
506         * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE},
507         * {@link Notification#DEFAULT_LIGHTS}.
508         * <p>
509         * For all default values, use {@link Notification#DEFAULT_ALL}.
510         */
511        public Builder setDefaults(int defaults) {
512            mNotification.defaults = defaults;
513            if ((defaults & Notification.DEFAULT_LIGHTS) != 0) {
514                mNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
515            }
516            return this;
517        }
518
519        private void setFlag(int mask, boolean value) {
520            if (value) {
521                mNotification.flags |= mask;
522            } else {
523                mNotification.flags &= ~mask;
524            }
525        }
526
527        /**
528         * Set the relative priority for this notification.
529         *
530         * Priority is an indication of how much of the user's
531         * valuable attention should be consumed by this
532         * notification. Low-priority notifications may be hidden from
533         * the user in certain situations, while the user might be
534         * interrupted for a higher-priority notification.
535         * The system sets a notification's priority based on various factors including the
536         * setPriority value. The effect may differ slightly on different platforms.
537         */
538        public Builder setPriority(int pri) {
539            mPriority = pri;
540            return this;
541        }
542
543        /**
544         * Add an action to this notification. Actions are typically displayed by
545         * the system as a button adjacent to the notification content.
546         * <br>
547         * Action buttons won't appear on platforms prior to Android 4.1. Action
548         * buttons depend on expanded notifications, which are only available in Android 4.1
549         * and later. To ensure that an action button's functionality is always available, first
550         * implement the functionality in the {@link android.app.Activity} that starts when a user
551         * clicks the  notification (see {@link #setContentIntent setContentIntent()}), and then
552         * enhance the notification by implementing the same functionality with
553         * {@link #addAction addAction()}.
554         *
555         * @param icon Resource ID of a drawable that represents the action.
556         * @param title Text describing the action.
557         * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked.
558         */
559        public Builder addAction(int icon, CharSequence title, PendingIntent intent) {
560            mActions.add(new Action(icon, title, intent));
561            return this;
562        }
563
564        /**
565         * Add a rich notification style to be applied at build time.
566         * <br>
567         * If the platform does not provide rich notification styles, this method has no effect. The
568         * user will always see the normal notification style.
569         *
570         * @param style Object responsible for modifying the notification style.
571         */
572        public Builder setStyle(Style style) {
573            if (mStyle != style) {
574                mStyle = style;
575                if (mStyle != null) {
576                    mStyle.setBuilder(this);
577                }
578            }
579            return this;
580        }
581
582        /**
583         * @deprecated Use {@link #build()} instead.
584         */
585        @Deprecated
586        public Notification getNotification() {
587            return (Notification) IMPL.build(this);
588        }
589
590        /**
591         * Combine all of the options that have been set and return a new {@link Notification}
592         * object.
593         */
594        public Notification build() {
595            return (Notification) IMPL.build(this);
596        }
597    }
598
599    /**
600     * An object that can apply a rich notification style to a {@link Notification.Builder}
601     * object.
602     * <br>
603     * If the platform does not provide rich notification styles, methods in this class have no
604     * effect.
605     */
606    public static abstract class Style
607    {
608        Builder mBuilder;
609        CharSequence mBigContentTitle;
610        CharSequence mSummaryText;
611        boolean mSummaryTextSet = false;
612
613        public void setBuilder(Builder builder) {
614            if (mBuilder != builder) {
615                mBuilder = builder;
616                if (mBuilder != null) {
617                    mBuilder.setStyle(this);
618                }
619            }
620        }
621
622        public Notification build() {
623            Notification notification = null;
624            if (mBuilder != null) {
625                notification = mBuilder.build();
626            }
627            return notification;
628        }
629    }
630
631    /**
632     * Helper class for generating large-format notifications that include a large image attachment.
633     * <br>
634     * If the platform does not provide large-format notifications, this method has no effect. The
635     * user will always see the normal notification view.
636     * <br>
637     * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
638     * <pre class="prettyprint">
639     * Notification noti = new Notification.Builder()
640     *     .setContentTitle(&quot;New photo from &quot; + sender.toString())
641     *     .setContentText(subject)
642     *     .setSmallIcon(R.drawable.new_post)
643     *     .setLargeIcon(aBitmap)
644     *     .setStyle(new Notification.BigPictureStyle()
645     *         .bigPicture(aBigBitmap))
646     *     .build();
647     * </pre>
648     *
649     * @see Notification#bigContentView
650     */
651    public static class BigPictureStyle extends Style {
652        Bitmap mPicture;
653        Bitmap mBigLargeIcon;
654        boolean mBigLargeIconSet;
655
656        public BigPictureStyle() {
657        }
658
659        public BigPictureStyle(Builder builder) {
660            setBuilder(builder);
661        }
662
663        /**
664         * Overrides ContentTitle in the big form of the template.
665         * This defaults to the value passed to setContentTitle().
666         */
667        public BigPictureStyle setBigContentTitle(CharSequence title) {
668            mBigContentTitle = title;
669            return this;
670        }
671
672        /**
673         * Set the first line of text after the detail section in the big form of the template.
674         */
675        public BigPictureStyle setSummaryText(CharSequence cs) {
676            mSummaryText = cs;
677            mSummaryTextSet = true;
678            return this;
679        }
680
681        /**
682         * Provide the bitmap to be used as the payload for the BigPicture notification.
683         */
684        public BigPictureStyle bigPicture(Bitmap b) {
685            mPicture = b;
686            return this;
687        }
688
689        /**
690         * Override the large icon when the big notification is shown.
691         */
692        public BigPictureStyle bigLargeIcon(Bitmap b) {
693            mBigLargeIcon = b;
694            mBigLargeIconSet = true;
695            return this;
696        }
697    }
698
699    /**
700     * Helper class for generating large-format notifications that include a lot of text.
701     *
702     * <br>
703     * If the platform does not provide large-format notifications, this method has no effect. The
704     * user will always see the normal notification view.
705     * <br>
706     * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
707     * <pre class="prettyprint">
708     * Notification noti = new Notification.Builder()
709     *     .setContentTitle(&quot;New mail from &quot; + sender.toString())
710     *     .setContentText(subject)
711     *     .setSmallIcon(R.drawable.new_mail)
712     *     .setLargeIcon(aBitmap)
713     *     .setStyle(new Notification.BigTextStyle()
714     *         .bigText(aVeryLongString))
715     *     .build();
716     * </pre>
717     *
718     * @see Notification#bigContentView
719     */
720    public static class BigTextStyle extends Style {
721        CharSequence mBigText;
722
723        public BigTextStyle() {
724        }
725
726        public BigTextStyle(Builder builder) {
727            setBuilder(builder);
728        }
729
730        /**
731         * Overrides ContentTitle in the big form of the template.
732         * This defaults to the value passed to setContentTitle().
733         */
734        public BigTextStyle setBigContentTitle(CharSequence title) {
735            mBigContentTitle = title;
736            return this;
737        }
738
739        /**
740         * Set the first line of text after the detail section in the big form of the template.
741         */
742        public BigTextStyle setSummaryText(CharSequence cs) {
743            mSummaryText = cs;
744            mSummaryTextSet = true;
745            return this;
746        }
747
748        /**
749         * Provide the longer text to be displayed in the big form of the
750         * template in place of the content text.
751         */
752        public BigTextStyle bigText(CharSequence cs) {
753            mBigText = cs;
754            return this;
755        }
756    }
757
758    /**
759     * Helper class for generating large-format notifications that include a list of (up to 5) strings.
760     *
761     * <br>
762     * If the platform does not provide large-format notifications, this method has no effect. The
763     * user will always see the normal notification view.
764     * <br>
765     * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
766     * <pre class="prettyprint">
767     * Notification noti = new Notification.Builder()
768     *     .setContentTitle(&quot;5 New mails from &quot; + sender.toString())
769     *     .setContentText(subject)
770     *     .setSmallIcon(R.drawable.new_mail)
771     *     .setLargeIcon(aBitmap)
772     *     .setStyle(new Notification.InboxStyle()
773     *         .addLine(str1)
774     *         .addLine(str2)
775     *         .setContentTitle(&quot;&quot;)
776     *         .setSummaryText(&quot;+3 more&quot;))
777     *     .build();
778     * </pre>
779     *
780     * @see Notification#bigContentView
781     */
782    public static class InboxStyle extends Style {
783        ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>();
784
785        public InboxStyle() {
786        }
787
788        public InboxStyle(Builder builder) {
789            setBuilder(builder);
790        }
791
792        /**
793         * Overrides ContentTitle in the big form of the template.
794         * This defaults to the value passed to setContentTitle().
795         */
796        public InboxStyle setBigContentTitle(CharSequence title) {
797            mBigContentTitle = title;
798            return this;
799        }
800
801        /**
802         * Set the first line of text after the detail section in the big form of the template.
803         */
804        public InboxStyle setSummaryText(CharSequence cs) {
805            mSummaryText = cs;
806            mSummaryTextSet = true;
807            return this;
808        }
809
810        /**
811         * Append a line to the digest section of the Inbox notification.
812         */
813        public InboxStyle addLine(CharSequence cs) {
814            mTexts.add(cs);
815            return this;
816        }
817    }
818
819    public static class Action {
820        public int icon;
821        public CharSequence title;
822        public PendingIntent actionIntent;
823
824        public Action(int icon_, CharSequence title_, PendingIntent intent_) {
825            this.icon = icon_;
826            this.title = title_;
827            this.actionIntent = intent_;
828        }
829    }
830}
831