NotificationCompat.java revision c9cf2eb0a9b6694d0fda3dbc313844955db60820
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;
28
29public class NotificationCompat {
30    /**
31     * Bit to be bitwise-ored into the {@link Notification#flags} field that should be set if
32     * this notification represents a high-priority event that may be shown to the user even
33     * if notifications are otherwise unavailable (that is, when the status bar is hidden).
34     * This flag is ideally used in conjunction with fullScreenIntent.
35     *
36     * <p>This will only be respected on API level 9 and above.</p>
37     */
38    public static final int FLAG_HIGH_PRIORITY = 0x00000080;
39
40    private static final NotificationCompatImpl IMPL;
41
42    interface NotificationCompatImpl {
43        public Notification getNotification(Builder b);
44    }
45
46    static class NotificationCompatImplBase implements NotificationCompatImpl {
47        public Notification getNotification(Builder b) {
48            Notification result = (Notification) b.mNotification;
49            result.setLatestEventInfo(b.mContext, b.mContentTitle,
50                    b.mContentText, b.mContentIntent);
51            return result;
52        }
53    }
54
55    static class NotificationCompatImplHoneycomb implements NotificationCompatImpl {
56        public Notification getNotification(Builder b) {
57            return NotificationCompatHoneycomb.add(b.mContext, b.mNotification,
58                    b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
59                    b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon);
60        }
61    }
62
63    static {
64        if (Build.VERSION.SDK_INT >= 11) {
65            IMPL = new NotificationCompatImplHoneycomb();
66        } else {
67            IMPL = new NotificationCompatImplBase();
68        }
69    }
70
71    /**
72     * Builder class for {@link Notification} objects.  Allows easier control over
73     * all the flags, as well as help constructing the typical notification layouts.
74     */
75    public static class Builder {
76        Context mContext;
77
78        CharSequence mContentTitle;
79        CharSequence mContentText;
80        PendingIntent mContentIntent;
81        PendingIntent mFullScreenIntent;
82        RemoteViews mTickerView;
83        Bitmap mLargeIcon;
84        CharSequence mContentInfo;
85        int mNumber;
86
87        Notification mNotification = new Notification();
88
89        /**
90         * Constructor.
91         *
92         * Automatically sets the when field to {@link System#currentTimeMillis()
93         * System.currentTimeMillis()} and the audio stream to the
94         * {@link Notification#STREAM_DEFAULT}.
95         *
96         * @param context A {@link Context} that will be used to construct the
97         *      RemoteViews. The Context will not be held past the lifetime of this
98         *      Builder object.
99         */
100        public Builder(Context context) {
101            mContext = context;
102
103            // Set defaults to match the defaults of a Notification
104            mNotification.when = System.currentTimeMillis();
105            mNotification.audioStreamType = Notification.STREAM_DEFAULT;
106        }
107
108        /**
109         * Set the time that the event occurred.  Notifications in the panel are
110         * sorted by this time.
111         */
112        public Builder setWhen(long when) {
113            mNotification.when = when;
114            return this;
115        }
116
117        /**
118         * Set the small icon to use in the notification layouts.  Different classes of devices
119         * may return different sizes.  See the UX guidelines for more information on how to
120         * design these icons.
121         *
122         * @param icon A resource ID in the application's package of the drawble to use.
123         */
124        public Builder setSmallIcon(int icon) {
125            mNotification.icon = icon;
126            return this;
127        }
128
129        /**
130         * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
131         * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
132         * LevelListDrawable}.
133         *
134         * @param icon A resource ID in the application's package of the drawble to use.
135         * @param level The level to use for the icon.
136         *
137         * @see android.graphics.drawable.LevelListDrawable
138         */
139        public Builder setSmallIcon(int icon, int level) {
140            mNotification.icon = icon;
141            mNotification.iconLevel = level;
142            return this;
143        }
144
145        /**
146         * Set the title (first row) of the notification, in a standard notification.
147         */
148        public Builder setContentTitle(CharSequence title) {
149            mContentTitle = title;
150            return this;
151        }
152
153        /**
154         * Set the text (second row) of the notification, in a standard notification.
155         */
156        public Builder setContentText(CharSequence text) {
157            mContentText = text;
158            return this;
159        }
160
161        /**
162         * Set the large number at the right-hand side of the notification.  This is
163         * equivalent to setContentInfo, although it might show the number in a different
164         * font size for readability.
165         */
166        public Builder setNumber(int number) {
167            mNumber = number;
168            return this;
169        }
170
171        /**
172         * Set the large text at the right-hand side of the notification.
173         */
174        public Builder setContentInfo(CharSequence info) {
175            mContentInfo = info;
176            return this;
177        }
178
179        /**
180         * Set the progress this notification represents, which may be
181         * represented as a {@link ProgressBar}.
182         */
183        /* TODO
184        public Builder setProgress(int max, int progress, boolean indeterminate) {
185            mProgressMax = max;
186            mProgress = progress;
187            mProgressIndeterminate = indeterminate;
188            return this;
189        }*/
190
191        /**
192         * Supply a custom RemoteViews to use instead of the standard one.
193         */
194        public Builder setContent(RemoteViews views) {
195            mNotification.contentView = views;
196            return this;
197        }
198
199        /**
200         * Supply a {@link PendingIntent} to send when the notification is clicked.
201         * If you do not supply an intent, you can now add PendingIntents to individual
202         * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
203         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.  Be sure to
204         * read {@link Notification#contentIntent Notification.contentIntent} for
205         * how to correctly use this.
206         */
207        public Builder setContentIntent(PendingIntent intent) {
208            mContentIntent = intent;
209            return this;
210        }
211
212        /**
213         * Supply a {@link PendingIntent} to send when the notification is cleared by the user
214         * directly from the notification panel.  For example, this intent is sent when the user
215         * clicks the "Clear all" button, or the individual "X" buttons on notifications.  This
216         * intent is not sent when the application calls {@link NotificationManager#cancel
217         * NotificationManager.cancel(int)}.
218         */
219        public Builder setDeleteIntent(PendingIntent intent) {
220            mNotification.deleteIntent = intent;
221            return this;
222        }
223
224        /**
225         * An intent to launch instead of posting the notification to the status bar.
226         * Only for use with extremely high-priority notifications demanding the user's
227         * <strong>immediate</strong> attention, such as an incoming phone call or
228         * alarm clock that the user has explicitly set to a particular time.
229         * If this facility is used for something else, please give the user an option
230         * to turn it off and use a normal notification, as this can be extremely
231         * disruptive.
232         *
233         * @param intent The pending intent to launch.
234         * @param highPriority Passing true will cause this notification to be sent
235         *          even if other notifications are suppressed.
236         */
237        public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
238            mFullScreenIntent = intent;
239            setFlag(FLAG_HIGH_PRIORITY, highPriority);
240            return this;
241        }
242
243        /**
244         * Set the text that is displayed in the status bar when the notification first
245         * arrives.
246         */
247        public Builder setTicker(CharSequence tickerText) {
248            mNotification.tickerText = tickerText;
249            return this;
250        }
251
252        /**
253         * Set the text that is displayed in the status bar when the notification first
254         * arrives, and also a RemoteViews object that may be displayed instead on some
255         * devices.
256         */
257        public Builder setTicker(CharSequence tickerText, RemoteViews views) {
258            mNotification.tickerText = tickerText;
259            mTickerView = views;
260            return this;
261        }
262
263        /**
264         * Set the large icon that is shown in the ticker and notification.
265         */
266        public Builder setLargeIcon(Bitmap icon) {
267            mLargeIcon = icon;
268            return this;
269        }
270
271        /**
272         * Set the sound to play.  It will play on the default stream.
273         */
274        public Builder setSound(Uri sound) {
275            mNotification.sound = sound;
276            mNotification.audioStreamType = Notification.STREAM_DEFAULT;
277            return this;
278        }
279
280        /**
281         * Set the sound to play.  It will play on the stream you supply.
282         *
283         * @see #STREAM_DEFAULT
284         * @see AudioManager for the <code>STREAM_</code> constants.
285         */
286        public Builder setSound(Uri sound, int streamType) {
287            mNotification.sound = sound;
288            mNotification.audioStreamType = streamType;
289            return this;
290        }
291
292        /**
293         * Set the vibration pattern to use.
294         *
295         * @see android.os.Vibrator for a discussion of the <code>pattern</code>
296         * parameter.
297         */
298        public Builder setVibrate(long[] pattern) {
299            mNotification.vibrate = pattern;
300            return this;
301        }
302
303        /**
304         * Set the argb value that you would like the LED on the device to blnk, as well as the
305         * rate.  The rate is specified in terms of the number of milliseconds to be on
306         * and then the number of milliseconds to be off.
307         */
308        public Builder setLights(int argb, int onMs, int offMs) {
309            mNotification.ledARGB = argb;
310            mNotification.ledOnMS = onMs;
311            mNotification.ledOffMS = offMs;
312            boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0;
313            mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) |
314                    (showLights ? Notification.FLAG_SHOW_LIGHTS : 0);
315            return this;
316        }
317
318        /**
319         * Set whether this is an ongoing notification.
320         *
321         * <p>Ongoing notifications differ from regular notifications in the following ways:
322         * <ul>
323         *   <li>Ongoing notifications are sorted above the regular notifications in the
324         *   notification panel.</li>
325         *   <li>Ongoing notifications do not have an 'X' close button, and are not affected
326         *   by the "Clear all" button.
327         * </ul>
328         */
329        public Builder setOngoing(boolean ongoing) {
330            setFlag(Notification.FLAG_ONGOING_EVENT, ongoing);
331            return this;
332        }
333
334        /**
335         * Set this flag if you would only like the sound, vibrate
336         * and ticker to be played if the notification is not already showing.
337         */
338        public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
339            setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
340            return this;
341        }
342
343        /**
344         * Setting this flag will make it so the notification is automatically
345         * canceled when the user clicks it in the panel.  The PendingIntent
346         * set with {@link #setDeleteIntent} will be broadcast when the notification
347         * is canceled.
348         */
349        public Builder setAutoCancel(boolean autoCancel) {
350            setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel);
351            return this;
352        }
353
354        /**
355         * Set the default notification options that will be used.
356         * <p>
357         * The value should be one or more of the following fields combined with
358         * bitwise-or:
359         * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE},
360         * {@link Notification#DEFAULT_LIGHTS}.
361         * <p>
362         * For all default values, use {@link Notification#DEFAULT_ALL}.
363         */
364        public Builder setDefaults(int defaults) {
365            mNotification.defaults = defaults;
366            if ((defaults & Notification.DEFAULT_LIGHTS) != 0) {
367                mNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
368            }
369            return this;
370        }
371
372        private void setFlag(int mask, boolean value) {
373            if (value) {
374                mNotification.flags |= mask;
375            } else {
376                mNotification.flags &= ~mask;
377            }
378        }
379
380        /**
381         * Combine all of the options that have been set and return a new {@link Notification}
382         * object.
383         */
384        public Notification getNotification() {
385            return (Notification) IMPL.getNotification(this);
386        }
387    }
388}
389