OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / java / android / app / Notification.java
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, in a new mail
87      * notification, this could be the number of unread messages.  This number is superimposed over
88      * the icon in the status bar.  If the number is 0 or negative, it is not shown in the status
89      * 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      * An intent to launch instead of posting the notification to the status bar.
113      * Only for use with extremely high-priority notifications demanding the user's
114      * <strong>immediate</strong> attention, such as an incoming phone call or
115      * alarm clock that the user has explicitly set to a particular time.
116      * If this facility is used for something else, please give the user an option
117      * to turn it off and use a normal notification, as this can be extremely
118      * disruptive.
119      */
120     public PendingIntent fullScreenIntent;
121
122     /**
123      * Text to scroll across the screen when this item is added to
124      * the status bar.
125      */
126     public CharSequence tickerText;
127
128     /**
129      * The view that will represent this notification in the expanded status bar.
130      */
131     public RemoteViews contentView;
132
133     /**
134      * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,
135      * leave it at its default value of 0.
136      *
137      * @see android.widget.ImageView#setImageLevel
138      * @see android.graphics.drawable#setLevel
139      */
140     public int iconLevel;
141
142     /**
143      * The sound to play.
144      * 
145      * <p>
146      * To play the default notification sound, see {@link #defaults}. 
147      * </p>
148      */
149     public Uri sound;
150
151     /**
152      * Use this constant as the value for audioStreamType to request that
153      * the default stream type for notifications be used.  Currently the
154      * default stream type is STREAM_RING.
155      */
156     public static final int STREAM_DEFAULT = -1;
157
158     /**
159      * The audio stream type to use when playing the sound.
160      * Should be one of the STREAM_ constants from
161      * {@link android.media.AudioManager}.
162      */
163     public int audioStreamType = STREAM_DEFAULT;
164
165     
166     /**
167      * The pattern with which to vibrate. 
168      * 
169      * <p>
170      * To vibrate the default pattern, see {@link #defaults}.
171      * </p>
172      * 
173      * @see android.os.Vibrator#vibrate(long[],int)
174      */
175     public long[] vibrate;
176
177     /**
178      * The color of the led.  The hardware will do its best approximation.
179      *
180      * @see #FLAG_SHOW_LIGHTS
181      * @see #flags
182      */
183     public int ledARGB;
184
185     /**
186      * The number of milliseconds for the LED to be on while it's flashing.
187      * The hardware will do its best approximation.
188      *
189      * @see #FLAG_SHOW_LIGHTS
190      * @see #flags
191      */
192     public int ledOnMS;
193
194     /**
195      * The number of milliseconds for the LED to be off while it's flashing.
196      * The hardware will do its best approximation.
197      *
198      * @see #FLAG_SHOW_LIGHTS
199      * @see #flags
200      */
201     public int ledOffMS;
202
203     /**
204      * Specifies which values should be taken from the defaults.
205      * <p>
206      * To set, OR the desired from {@link #DEFAULT_SOUND},
207      * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
208      * values, use {@link #DEFAULT_ALL}.
209      * </p>
210      */
211     public int defaults;
212
213
214     /**
215      * Bit to be bitwise-ored into the {@link #flags} field that should be
216      * set if you want the LED on for this notification.
217      * <ul>
218      * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
219      *      or 0 for both ledOnMS and ledOffMS.</li>
220      * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
221      * <li>To flash the LED, pass the number of milliseconds that it should
222      *      be on and off to ledOnMS and ledOffMS.</li>
223      * </ul>
224      * <p>
225      * Since hardware varies, you are not guaranteed that any of the values
226      * you pass are honored exactly.  Use the system defaults (TODO) if possible
227      * because they will be set to values that work on any given hardware.
228      * <p>
229      * The alpha channel must be set for forward compatibility.
230      * 
231      */
232     public static final int FLAG_SHOW_LIGHTS        = 0x00000001;
233
234     /**
235      * Bit to be bitwise-ored into the {@link #flags} field that should be
236      * set if this notification is in reference to something that is ongoing,
237      * like a phone call.  It should not be set if this notification is in
238      * reference to something that happened at a particular point in time,
239      * like a missed phone call.
240      */
241     public static final int FLAG_ONGOING_EVENT      = 0x00000002;
242
243     /**
244      * Bit to be bitwise-ored into the {@link #flags} field that if set,
245      * the audio will be repeated until the notification is
246      * cancelled or the notification window is opened.
247      */
248     public static final int FLAG_INSISTENT          = 0x00000004;
249
250     /**
251      * Bit to be bitwise-ored into the {@link #flags} field that should be
252      * set if you want the sound and/or vibration play each time the
253      * notification is sent, even if it has not been canceled before that.
254      */
255     public static final int FLAG_ONLY_ALERT_ONCE    = 0x00000008;
256
257     /**
258      * Bit to be bitwise-ored into the {@link #flags} field that should be
259      * set if the notification should be canceled when it is clicked by the
260      * user. 
261      */
262     public static final int FLAG_AUTO_CANCEL        = 0x00000010;
263
264     /**
265      * Bit to be bitwise-ored into the {@link #flags} field that should be
266      * set if the notification should not be canceled when the user clicks
267      * the Clear all button.
268      */
269     public static final int FLAG_NO_CLEAR           = 0x00000020;
270
271     /**
272      * Bit to be bitwise-ored into the {@link #flags} field that should be
273      * set if this notification represents a currently running service.  This
274      * will normally be set for you by {@link Service#startForeground}.
275      */
276     public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
277
278     public int flags;
279
280     /**
281      * Constructs a Notification object with everything set to 0.
282      */
283     public Notification()
284     {
285         this.when = System.currentTimeMillis();
286     }
287
288     /**
289      * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
290      * @hide
291      */
292     public Notification(Context context, int icon, CharSequence tickerText, long when,
293             CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
294     {
295         this.when = when;
296         this.icon = icon;
297         this.tickerText = tickerText;
298         setLatestEventInfo(context, contentTitle, contentText,
299                 PendingIntent.getActivity(context, 0, contentIntent, 0));
300     }
301
302     /**
303      * Constructs a Notification object with the information needed to
304      * have a status bar icon without the standard expanded view.
305      *
306      * @param icon          The resource id of the icon to put in the status bar.
307      * @param tickerText    The text that flows by in the status bar when the notification first
308      *                      activates.
309      * @param when          The time to show in the time field.  In the System.currentTimeMillis
310      *                      timebase.
311      */
312     public Notification(int icon, CharSequence tickerText, long when)
313     {
314         this.icon = icon;
315         this.tickerText = tickerText;
316         this.when = when;
317     }
318
319     /**
320      * Unflatten the notification from a parcel.
321      */
322     public Notification(Parcel parcel)
323     {
324         int version = parcel.readInt();
325
326         when = parcel.readLong();
327         icon = parcel.readInt();
328         number = parcel.readInt();
329         if (parcel.readInt() != 0) {
330             contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
331         }
332         if (parcel.readInt() != 0) {
333             deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
334         }
335         if (parcel.readInt() != 0) {
336             tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
337         }
338         if (parcel.readInt() != 0) {
339             contentView = RemoteViews.CREATOR.createFromParcel(parcel);
340         }
341         defaults = parcel.readInt();
342         flags = parcel.readInt();
343         if (parcel.readInt() != 0) {
344             sound = Uri.CREATOR.createFromParcel(parcel);
345         }
346
347         audioStreamType = parcel.readInt();
348         vibrate = parcel.createLongArray();
349         ledARGB = parcel.readInt();
350         ledOnMS = parcel.readInt();
351         ledOffMS = parcel.readInt();
352         iconLevel = parcel.readInt();
353
354         if (parcel.readInt() != 0) {
355             fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
356         }
357     }
358
359     public Notification clone() {
360         Notification that = new Notification();
361
362         that.when = this.when;
363         that.icon = this.icon;
364         that.number = this.number;
365
366         // PendingIntents are global, so there's no reason (or way) to clone them.
367         that.contentIntent = this.contentIntent;
368         that.deleteIntent = this.deleteIntent;
369         that.fullScreenIntent = this.fullScreenIntent;
370
371         if (this.tickerText != null) {
372             that.tickerText = this.tickerText.toString();
373         }
374         if (this.contentView != null) {
375             that.contentView = this.contentView.clone();
376         }
377         that.iconLevel = that.iconLevel;
378         that.sound = this.sound; // android.net.Uri is immutable
379         that.audioStreamType = this.audioStreamType;
380
381         final long[] vibrate = this.vibrate;
382         if (vibrate != null) {
383             final int N = vibrate.length;
384             final long[] vib = that.vibrate = new long[N];
385             System.arraycopy(vibrate, 0, vib, 0, N);
386         }
387
388         that.ledARGB = this.ledARGB;
389         that.ledOnMS = this.ledOnMS;
390         that.ledOffMS = this.ledOffMS;
391         that.defaults = this.defaults;
392         
393         that.flags = this.flags;
394
395         return that;
396     }
397
398     public int describeContents() {
399         return 0;
400     }
401
402     /**
403      * Flatten this notification from a parcel.
404      */
405     public void writeToParcel(Parcel parcel, int flags)
406     {
407         parcel.writeInt(1);
408
409         parcel.writeLong(when);
410         parcel.writeInt(icon);
411         parcel.writeInt(number);
412         if (contentIntent != null) {
413             parcel.writeInt(1);
414             contentIntent.writeToParcel(parcel, 0);
415         } else {
416             parcel.writeInt(0);
417         }
418         if (deleteIntent != null) {
419             parcel.writeInt(1);
420             deleteIntent.writeToParcel(parcel, 0);
421         } else {
422             parcel.writeInt(0);
423         }
424         if (tickerText != null) {
425             parcel.writeInt(1);
426             TextUtils.writeToParcel(tickerText, parcel, flags);
427         } else {
428             parcel.writeInt(0);
429         }
430         if (contentView != null) {
431             parcel.writeInt(1);
432             contentView.writeToParcel(parcel, 0);
433         } else {
434             parcel.writeInt(0);
435         }
436
437         parcel.writeInt(defaults);
438         parcel.writeInt(this.flags);
439
440         if (sound != null) {
441             parcel.writeInt(1);
442             sound.writeToParcel(parcel, 0);
443         } else {
444             parcel.writeInt(0);
445         }
446         parcel.writeInt(audioStreamType);
447         parcel.writeLongArray(vibrate);
448         parcel.writeInt(ledARGB);
449         parcel.writeInt(ledOnMS);
450         parcel.writeInt(ledOffMS);
451         parcel.writeInt(iconLevel);
452
453         if (fullScreenIntent != null) {
454             parcel.writeInt(1);
455             fullScreenIntent.writeToParcel(parcel, 0);
456         } else {
457             parcel.writeInt(0);
458         }
459     }
460
461     /**
462      * Parcelable.Creator that instantiates Notification objects
463      */
464     public static final Parcelable.Creator<Notification> CREATOR
465             = new Parcelable.Creator<Notification>()
466     {
467         public Notification createFromParcel(Parcel parcel)
468         {
469             return new Notification(parcel);
470         }
471
472         public Notification[] newArray(int size)
473         {
474             return new Notification[size];
475         }
476     };
477
478     /**
479      * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
480      * layout.
481      *
482      * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
483      * in the view.</p>
484      * @param context       The context for your application / activity.
485      * @param contentTitle The title that goes in the expanded entry.
486      * @param contentText  The text that goes in the expanded entry.
487      * @param contentIntent The intent to launch when the user clicks the expanded notification.
488      * If this is an activity, it must include the
489      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
490      * that you take care of task management as described in 
491      * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
492      */
493     public void setLatestEventInfo(Context context,
494             CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
495         RemoteViews contentView = new RemoteViews(context.getPackageName(),
496                 com.android.internal.R.layout.status_bar_latest_event_content);
497         if (this.icon != 0) {
498             contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
499         }
500         if (contentTitle != null) {
501             contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
502         }
503         if (contentText != null) {
504             contentView.setTextViewText(com.android.internal.R.id.text, contentText);
505         }
506         if (this.when != 0) {
507             contentView.setLong(com.android.internal.R.id.time, "setTime", when);
508         }
509
510         this.contentView = contentView;
511         this.contentIntent = contentIntent;
512     }
513
514     @Override
515     public String toString() {
516         StringBuilder sb = new StringBuilder();
517         sb.append("Notification(vibrate=");
518         if (this.vibrate != null) {
519             int N = this.vibrate.length-1;
520             sb.append("[");
521             for (int i=0; i<N; i++) {
522                 sb.append(this.vibrate[i]);
523                 sb.append(',');
524             }
525             if (N != -1) {
526                 sb.append(this.vibrate[N]);
527             }
528             sb.append("]");
529         } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
530             sb.append("default");
531         } else {
532             sb.append("null");
533         }
534         sb.append(",sound=");
535         if (this.sound != null) {
536             sb.append(this.sound.toString());
537         } else if ((this.defaults & DEFAULT_SOUND) != 0) {
538             sb.append("default");
539         } else {
540             sb.append("null");
541         }
542         sb.append(",defaults=0x");
543         sb.append(Integer.toHexString(this.defaults));
544         sb.append(",flags=0x");
545         sb.append(Integer.toHexString(this.flags));
546         sb.append(")");
547         return sb.toString();
548     }
549 }