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