Notification.java revision d45c9f4ceb5228912fe51c31fa7554a8e9bbfd6f
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
17package android.app;
18
19import java.util.Date;
20
21import android.app.PendingIntent;
22import android.content.Context;
23import android.content.Intent;
24import android.media.AudioManager;
25import android.net.Uri;
26import android.os.Parcel;
27import android.os.Parcelable;
28import android.text.TextUtils;
29import android.text.format.DateFormat;
30import android.text.format.DateUtils;
31import 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 */
41public 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    public int flags;
261
262    /**
263     * Constructs a Notification object with everything set to 0.
264     */
265    public Notification()
266    {
267        this.when = System.currentTimeMillis();
268    }
269
270    /**
271     * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
272     * @hide
273     */
274    public Notification(Context context, int icon, CharSequence tickerText, long when,
275            CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
276    {
277        this.when = when;
278        this.icon = icon;
279        this.tickerText = tickerText;
280        setLatestEventInfo(context, contentTitle, contentText,
281                PendingIntent.getActivity(context, 0, contentIntent, 0));
282    }
283
284    /**
285     * Constructs a Notification object with the information needed to
286     * have a status bar icon without the standard expanded view.
287     *
288     * @param icon          The resource id of the icon to put in the status bar.
289     * @param tickerText    The text that flows by in the status bar when the notification first
290     *                      activates.
291     * @param when          The time to show in the time field.  In the System.currentTimeMillis
292     *                      timebase.
293     */
294    public Notification(int icon, CharSequence tickerText, long when)
295    {
296        this.icon = icon;
297        this.tickerText = tickerText;
298        this.when = when;
299    }
300
301    /**
302     * Unflatten the notification from a parcel.
303     */
304    public Notification(Parcel parcel)
305    {
306        int version = parcel.readInt();
307
308        when = parcel.readLong();
309        icon = parcel.readInt();
310        number = parcel.readInt();
311        if (parcel.readInt() != 0) {
312            contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
313        }
314        if (parcel.readInt() != 0) {
315            deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
316        }
317        if (parcel.readInt() != 0) {
318            tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
319        }
320        if (parcel.readInt() != 0) {
321            contentView = RemoteViews.CREATOR.createFromParcel(parcel);
322        }
323        defaults = parcel.readInt();
324        flags = parcel.readInt();
325        if (parcel.readInt() != 0) {
326            sound = Uri.CREATOR.createFromParcel(parcel);
327        }
328
329        audioStreamType = parcel.readInt();
330        vibrate = parcel.createLongArray();
331        ledARGB = parcel.readInt();
332        ledOnMS = parcel.readInt();
333        ledOffMS = parcel.readInt();
334        iconLevel = parcel.readInt();
335    }
336
337    public int describeContents() {
338        return 0;
339    }
340
341    /**
342     * Flatten this notification from a parcel.
343     */
344    public void writeToParcel(Parcel parcel, int flags)
345    {
346        parcel.writeInt(1);
347
348        parcel.writeLong(when);
349        parcel.writeInt(icon);
350        parcel.writeInt(number);
351        if (contentIntent != null) {
352            parcel.writeInt(1);
353            contentIntent.writeToParcel(parcel, 0);
354        } else {
355            parcel.writeInt(0);
356        }
357        if (deleteIntent != null) {
358            parcel.writeInt(1);
359            deleteIntent.writeToParcel(parcel, 0);
360        } else {
361            parcel.writeInt(0);
362        }
363        if (tickerText != null) {
364            parcel.writeInt(1);
365            TextUtils.writeToParcel(tickerText, parcel, flags);
366        } else {
367            parcel.writeInt(0);
368        }
369        if (contentView != null) {
370            parcel.writeInt(1);
371            contentView.writeToParcel(parcel, 0);
372        } else {
373            parcel.writeInt(0);
374        }
375
376        parcel.writeInt(defaults);
377        parcel.writeInt(this.flags);
378
379        if (sound != null) {
380            parcel.writeInt(1);
381            sound.writeToParcel(parcel, 0);
382        } else {
383            parcel.writeInt(0);
384        }
385        parcel.writeInt(audioStreamType);
386        parcel.writeLongArray(vibrate);
387        parcel.writeInt(ledARGB);
388        parcel.writeInt(ledOnMS);
389        parcel.writeInt(ledOffMS);
390        parcel.writeInt(iconLevel);
391    }
392
393    /**
394     * Parcelable.Creator that instantiates Notification objects
395     */
396    public static final Parcelable.Creator<Notification> CREATOR
397            = new Parcelable.Creator<Notification>()
398    {
399        public Notification createFromParcel(Parcel parcel)
400        {
401            return new Notification(parcel);
402        }
403
404        public Notification[] newArray(int size)
405        {
406            return new Notification[size];
407        }
408    };
409
410    /**
411     * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
412     * layout.
413     *
414     * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
415     * in the view.</p>
416     * @param context       The context for your application / activity.
417     * @param contentTitle The title that goes in the expanded entry.
418     * @param contentText  The text that goes in the expanded entry.
419     * @param contentIntent The intent to launch when the user clicks the expanded notification.
420     * If this is an activity, it must include the
421     * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
422     * that you take care of task management as described in
423     * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
424     */
425    public void setLatestEventInfo(Context context,
426            CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
427        RemoteViews contentView = new RemoteViews(context.getPackageName(),
428                com.android.internal.R.layout.status_bar_latest_event_content);
429        if (this.icon != 0) {
430            contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
431        }
432        if (contentTitle != null) {
433            contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
434        }
435        if (contentText != null) {
436            contentView.setTextViewText(com.android.internal.R.id.text, contentText);
437        }
438        if (this.when != 0) {
439            Date date = new Date(when);
440            CharSequence str =
441                DateUtils.isToday(when) ? DateFormat.getTimeFormat(context).format(date)
442                    : DateFormat.getDateFormat(context).format(date);
443            contentView.setTextViewText(com.android.internal.R.id.time, str);
444        }
445
446        this.contentView = contentView;
447        this.contentIntent = contentIntent;
448    }
449
450    @Override
451    public String toString() {
452        StringBuilder sb = new StringBuilder();
453        sb.append("Notification(vibrate=");
454        if (this.vibrate != null) {
455            int N = this.vibrate.length-1;
456            sb.append("[");
457            for (int i=0; i<N; i++) {
458                sb.append(this.vibrate[i]);
459                sb.append(',');
460            }
461	    if (N != -1) {
462        	sb.append(this.vibrate[N]);
463	    }
464            sb.append("]");
465        } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
466            sb.append("default");
467        } else {
468            sb.append("null");
469        }
470        sb.append(",sound=");
471        if (this.sound != null) {
472            sb.append(this.sound.toString());
473        } else if ((this.defaults & DEFAULT_SOUND) != 0) {
474            sb.append("default");
475        } else {
476            sb.append("null");
477        }
478        sb.append(",defaults=0x");
479        sb.append(Integer.toHexString(this.defaults));
480        sb.append(")");
481        return sb.toString();
482    }
483}
484