• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 
17 package android.app;
18 
19 import java.util.Date;
20 
21 import android.app.PendingIntent;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.media.AudioManager;
25 import android.net.Uri;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.text.TextUtils;
29 import android.text.format.DateFormat;
30 import android.text.format.DateUtils;
31 import android.widget.RemoteViews;
32 
33 /**
34  * A class that represents how a persistent notification is to be presented to
35  * the user using the {@link android.app.NotificationManager}.
36  *
37  * <p>For a guide to creating notifications, see the
38  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
39  * Bar Notifications</a> document in the Dev Guide.</p>
40  */
41 public class Notification implements Parcelable
42 {
43     /**
44      * Use all default values (where applicable).
45      */
46     public static final int DEFAULT_ALL = ~0;
47 
48     /**
49      * Use the default notification sound. This will ignore any given
50      * {@link #sound}.
51      *
52      * @see #defaults
53      */
54     public static final int DEFAULT_SOUND = 1;
55 
56     /**
57      * Use the default notification vibrate. This will ignore any given
58      * {@link #vibrate}. Using phone vibration requires the
59      * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
60      *
61      * @see #defaults
62      */
63     public static final int DEFAULT_VIBRATE = 2;
64 
65     /**
66      * Use the default notification lights. This will ignore the
67      * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
68      * {@link #ledOnMS}.
69      *
70      * @see #defaults
71      */
72     public static final int DEFAULT_LIGHTS = 4;
73 
74     /**
75      * The timestamp for the notification.  The icons and expanded views
76      * are sorted by this key.
77      */
78     public long when;
79 
80     /**
81      * The resource id of a drawable to use as the icon in the status bar.
82      */
83     public int icon;
84 
85     /**
86      * The number of events that this notification represents.  For example, if this is the
87      * new mail notification, this would be the number of unread messages.  This number is
88      * be superimposed over the icon in the status bar.  If the number is 0 or negative, it
89      * is not shown in the status bar.
90      */
91     public int number;
92 
93     /**
94      * The intent to execute when the expanded status entry is clicked.  If
95      * this is an activity, it must include the
96      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
97      * that you take care of task management as described in the <em>Activities and Tasks</em>
98      * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application
99      * Fundamentals</a> document.
100      */
101     public PendingIntent contentIntent;
102 
103     /**
104      * The intent to execute when the status entry is deleted by the user
105      * with the "Clear All Notifications" button. This probably shouldn't
106      * be launching an activity since several of those will be sent at the
107      * same time.
108      */
109     public PendingIntent deleteIntent;
110 
111     /**
112      * Text to scroll across the screen when this item is added to
113      * the status bar.
114      */
115     public CharSequence tickerText;
116 
117     /**
118      * The view that shows when this notification is shown in the expanded status bar.
119      */
120     public RemoteViews contentView;
121 
122     /**
123      * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,
124      * leave it at its default value of 0.
125      *
126      * @see android.widget.ImageView#setImageLevel
127      * @see android.graphics.drawable#setLevel
128      */
129     public int iconLevel;
130 
131     /**
132      * The sound to play.
133      *
134      * <p>
135      * To play the default notification sound, see {@link #defaults}.
136      * </p>
137      */
138     public Uri sound;
139 
140     /**
141      * Use this constant as the value for audioStreamType to request that
142      * the default stream type for notifications be used.  Currently the
143      * default stream type is STREAM_RING.
144      */
145     public static final int STREAM_DEFAULT = -1;
146 
147     /**
148      * The audio stream type to use when playing the sound.
149      * Should be one of the STREAM_ constants from
150      * {@link android.media.AudioManager}.
151      */
152     public int audioStreamType = STREAM_DEFAULT;
153 
154 
155     /**
156      * The pattern with which to vibrate.
157      *
158      * <p>
159      * To vibrate the default pattern, see {@link #defaults}.
160      * </p>
161      *
162      * @see android.os.Vibrator#vibrate(long[],int)
163      */
164     public long[] vibrate;
165 
166     /**
167      * The color of the led.  The hardware will do its best approximation.
168      *
169      * @see #FLAG_SHOW_LIGHTS
170      * @see #flags
171      */
172     public int ledARGB;
173 
174     /**
175      * The number of milliseconds for the LED to be on while it's flashing.
176      * The hardware will do its best approximation.
177      *
178      * @see #FLAG_SHOW_LIGHTS
179      * @see #flags
180      */
181     public int ledOnMS;
182 
183     /**
184      * The number of milliseconds for the LED to be off while it's flashing.
185      * The hardware will do its best approximation.
186      *
187      * @see #FLAG_SHOW_LIGHTS
188      * @see #flags
189      */
190     public int ledOffMS;
191 
192     /**
193      * Specifies which values should be taken from the defaults.
194      * <p>
195      * To set, OR the desired from {@link #DEFAULT_SOUND},
196      * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
197      * values, use {@link #DEFAULT_ALL}.
198      * </p>
199      */
200     public int defaults;
201 
202 
203     /**
204      * Bit to be bitwise-ored into the {@link #flags} field that should be
205      * set if you want the LED on for this notification.
206      * <ul>
207      * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
208      *      or 0 for both ledOnMS and ledOffMS.</li>
209      * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
210      * <li>To flash the LED, pass the number of milliseconds that it should
211      *      be on and off to ledOnMS and ledOffMS.</li>
212      * </ul>
213      * <p>
214      * Since hardware varies, you are not guaranteed that any of the values
215      * you pass are honored exactly.  Use the system defaults (TODO) if possible
216      * because they will be set to values that work on any given hardware.
217      * <p>
218      * The alpha channel must be set for forward compatibility.
219      *
220      */
221     public static final int FLAG_SHOW_LIGHTS        = 0x00000001;
222 
223     /**
224      * Bit to be bitwise-ored into the {@link #flags} field that should be
225      * set if this notification is in reference to something that is ongoing,
226      * like a phone call.  It should not be set if this notification is in
227      * reference to something that happened at a particular point in time,
228      * like a missed phone call.
229      */
230     public static final int FLAG_ONGOING_EVENT      = 0x00000002;
231 
232     /**
233      * Bit to be bitwise-ored into the {@link #flags} field that if set,
234      * the audio will be repeated until the notification is
235      * cancelled or the notification window is opened.
236      */
237     public static final int FLAG_INSISTENT          = 0x00000004;
238 
239     /**
240      * Bit to be bitwise-ored into the {@link #flags} field that should be
241      * set if you want the sound and/or vibration play each time the
242      * notification is sent, even if it has not been canceled before that.
243      */
244     public static final int FLAG_ONLY_ALERT_ONCE    = 0x00000008;
245 
246     /**
247      * Bit to be bitwise-ored into the {@link #flags} field that should be
248      * set if the notification should be canceled when it is clicked by the
249      * user.
250      */
251     public static final int FLAG_AUTO_CANCEL        = 0x00000010;
252 
253     /**
254      * Bit to be bitwise-ored into the {@link #flags} field that should be
255      * set if the notification should not be canceled when the user clicks
256      * the Clear all button.
257      */
258     public static final int FLAG_NO_CLEAR           = 0x00000020;
259 
260     /**
261      * Bit to be bitwise-ored into the {@link #flags} field that should be
262      * set if this notification represents a currently running service.  This
263      * will normally be set for you by {@link Service#startForeground}.
264      */
265     public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
266 
267     public int flags;
268 
269     /**
270      * Constructs a Notification object with everything set to 0.
271      */
Notification()272     public Notification()
273     {
274         this.when = System.currentTimeMillis();
275     }
276 
277     /**
278      * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
279      * @hide
280      */
Notification(Context context, int icon, CharSequence tickerText, long when, CharSequence contentTitle, CharSequence contentText, Intent contentIntent)281     public Notification(Context context, int icon, CharSequence tickerText, long when,
282             CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
283     {
284         this.when = when;
285         this.icon = icon;
286         this.tickerText = tickerText;
287         setLatestEventInfo(context, contentTitle, contentText,
288                 PendingIntent.getActivity(context, 0, contentIntent, 0));
289     }
290 
291     /**
292      * Constructs a Notification object with the information needed to
293      * have a status bar icon without the standard expanded view.
294      *
295      * @param icon          The resource id of the icon to put in the status bar.
296      * @param tickerText    The text that flows by in the status bar when the notification first
297      *                      activates.
298      * @param when          The time to show in the time field.  In the System.currentTimeMillis
299      *                      timebase.
300      */
Notification(int icon, CharSequence tickerText, long when)301     public Notification(int icon, CharSequence tickerText, long when)
302     {
303         this.icon = icon;
304         this.tickerText = tickerText;
305         this.when = when;
306     }
307 
308     /**
309      * Unflatten the notification from a parcel.
310      */
Notification(Parcel parcel)311     public Notification(Parcel parcel)
312     {
313         int version = parcel.readInt();
314 
315         when = parcel.readLong();
316         icon = parcel.readInt();
317         number = parcel.readInt();
318         if (parcel.readInt() != 0) {
319             contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
320         }
321         if (parcel.readInt() != 0) {
322             deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
323         }
324         if (parcel.readInt() != 0) {
325             tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
326         }
327         if (parcel.readInt() != 0) {
328             contentView = RemoteViews.CREATOR.createFromParcel(parcel);
329         }
330         defaults = parcel.readInt();
331         flags = parcel.readInt();
332         if (parcel.readInt() != 0) {
333             sound = Uri.CREATOR.createFromParcel(parcel);
334         }
335 
336         audioStreamType = parcel.readInt();
337         vibrate = parcel.createLongArray();
338         ledARGB = parcel.readInt();
339         ledOnMS = parcel.readInt();
340         ledOffMS = parcel.readInt();
341         iconLevel = parcel.readInt();
342     }
343 
describeContents()344     public int describeContents() {
345         return 0;
346     }
347 
348     /**
349      * Flatten this notification from a parcel.
350      */
writeToParcel(Parcel parcel, int flags)351     public void writeToParcel(Parcel parcel, int flags)
352     {
353         parcel.writeInt(1);
354 
355         parcel.writeLong(when);
356         parcel.writeInt(icon);
357         parcel.writeInt(number);
358         if (contentIntent != null) {
359             parcel.writeInt(1);
360             contentIntent.writeToParcel(parcel, 0);
361         } else {
362             parcel.writeInt(0);
363         }
364         if (deleteIntent != null) {
365             parcel.writeInt(1);
366             deleteIntent.writeToParcel(parcel, 0);
367         } else {
368             parcel.writeInt(0);
369         }
370         if (tickerText != null) {
371             parcel.writeInt(1);
372             TextUtils.writeToParcel(tickerText, parcel, flags);
373         } else {
374             parcel.writeInt(0);
375         }
376         if (contentView != null) {
377             parcel.writeInt(1);
378             contentView.writeToParcel(parcel, 0);
379         } else {
380             parcel.writeInt(0);
381         }
382 
383         parcel.writeInt(defaults);
384         parcel.writeInt(this.flags);
385 
386         if (sound != null) {
387             parcel.writeInt(1);
388             sound.writeToParcel(parcel, 0);
389         } else {
390             parcel.writeInt(0);
391         }
392         parcel.writeInt(audioStreamType);
393         parcel.writeLongArray(vibrate);
394         parcel.writeInt(ledARGB);
395         parcel.writeInt(ledOnMS);
396         parcel.writeInt(ledOffMS);
397         parcel.writeInt(iconLevel);
398     }
399 
400     /**
401      * Parcelable.Creator that instantiates Notification objects
402      */
403     public static final Parcelable.Creator<Notification> CREATOR
404             = new Parcelable.Creator<Notification>()
405     {
406         public Notification createFromParcel(Parcel parcel)
407         {
408             return new Notification(parcel);
409         }
410 
411         public Notification[] newArray(int size)
412         {
413             return new Notification[size];
414         }
415     };
416 
417     /**
418      * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
419      * layout.
420      *
421      * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
422      * in the view.</p>
423      * @param context       The context for your application / activity.
424      * @param contentTitle The title that goes in the expanded entry.
425      * @param contentText  The text that goes in the expanded entry.
426      * @param contentIntent The intent to launch when the user clicks the expanded notification.
427      * If this is an activity, it must include the
428      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
429      * that you take care of task management as described in
430      * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
431      */
setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent)432     public void setLatestEventInfo(Context context,
433             CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
434         RemoteViews contentView = new RemoteViews(context.getPackageName(),
435                 com.android.internal.R.layout.status_bar_latest_event_content);
436         if (this.icon != 0) {
437             contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
438         }
439         if (contentTitle != null) {
440             contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
441         }
442         if (contentText != null) {
443             contentView.setTextViewText(com.android.internal.R.id.text, contentText);
444         }
445         if (this.when != 0) {
446             Date date = new Date(when);
447             CharSequence str =
448                 DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date)
449                     : DateFormat.getDateFormat(context).format(date);
450             contentView.setTextViewText(com.android.internal.R.id.time, str);
451         }
452 
453         this.contentView = contentView;
454         this.contentIntent = contentIntent;
455     }
456 
457     @Override
toString()458     public String toString() {
459         StringBuilder sb = new StringBuilder();
460         sb.append("Notification(vibrate=");
461         if (this.vibrate != null) {
462             int N = this.vibrate.length-1;
463             sb.append("[");
464             for (int i=0; i<N; i++) {
465                 sb.append(this.vibrate[i]);
466                 sb.append(',');
467             }
468             if (N != -1) {
469                 sb.append(this.vibrate[N]);
470             }
471             sb.append("]");
472         } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
473             sb.append("default");
474         } else {
475             sb.append("null");
476         }
477         sb.append(",sound=");
478         if (this.sound != null) {
479             sb.append(this.sound.toString());
480         } else if ((this.defaults & DEFAULT_SOUND) != 0) {
481             sb.append("default");
482         } else {
483             sb.append("null");
484         }
485         sb.append(",defaults=0x");
486         sb.append(Integer.toHexString(this.defaults));
487         sb.append(")");
488         return sb.toString();
489     }
490 }
491