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