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