blob: 739aca35ff604f3f0e0852901eddcdc3dd5af8f4 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 *
Scott Mainb8b36452009-04-26 15:50:49 -070037 * <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>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 */
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
Scott Mainb8b36452009-04-26 15:50:49 -070058 * {@link #vibrate}. Using phone vibration requires the
59 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 *
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 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700156 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 *
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,
Scott Mainb8b36452009-04-26 15:50:49 -0700234 * the audio will be repeated until the notification is
235 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 */
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
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700260 /**
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 public int flags;
268
269 /**
270 * Constructs a Notification object with everything set to 0.
271 */
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 */
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 */
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 */
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
Joe Onorato18e69df2010-05-17 22:26:12 -0700344 public Notification clone() {
345 Notification that = new Notification();
346
347 that.when = this.when;
348 that.icon = this.icon;
349 that.number = this.number;
350
351 // PendingIntents are global, so there's no reason (or way) to clone them.
352 that.contentIntent = this.contentIntent;
353 that.deleteIntent = this.deleteIntent;
354
355 if (this.tickerText != null) {
356 that.tickerText = this.tickerText.toString();
357 }
358 if (this.contentView != null) {
359 that.contentView = this.contentView.clone();
360 }
361 that.iconLevel = that.iconLevel;
362 that.sound = this.sound; // android.net.Uri is immutable
363 that.audioStreamType = this.audioStreamType;
364
365 final long[] vibrate = this.vibrate;
366 if (vibrate != null) {
367 final int N = vibrate.length;
368 final long[] vib = that.vibrate = new long[N];
369 System.arraycopy(vibrate, 0, vib, 0, N);
370 }
371
372 that.ledARGB = this.ledARGB;
373 that.ledOnMS = this.ledOnMS;
374 that.ledOffMS = this.ledOffMS;
375 that.defaults = this.defaults;
376
377 that.flags = this.flags;
378
379 return that;
380 }
381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 public int describeContents() {
383 return 0;
384 }
385
386 /**
387 * Flatten this notification from a parcel.
388 */
389 public void writeToParcel(Parcel parcel, int flags)
390 {
391 parcel.writeInt(1);
392
393 parcel.writeLong(when);
394 parcel.writeInt(icon);
395 parcel.writeInt(number);
396 if (contentIntent != null) {
397 parcel.writeInt(1);
398 contentIntent.writeToParcel(parcel, 0);
399 } else {
400 parcel.writeInt(0);
401 }
402 if (deleteIntent != null) {
403 parcel.writeInt(1);
404 deleteIntent.writeToParcel(parcel, 0);
405 } else {
406 parcel.writeInt(0);
407 }
408 if (tickerText != null) {
409 parcel.writeInt(1);
410 TextUtils.writeToParcel(tickerText, parcel, flags);
411 } else {
412 parcel.writeInt(0);
413 }
414 if (contentView != null) {
415 parcel.writeInt(1);
416 contentView.writeToParcel(parcel, 0);
417 } else {
418 parcel.writeInt(0);
419 }
420
421 parcel.writeInt(defaults);
422 parcel.writeInt(this.flags);
423
424 if (sound != null) {
425 parcel.writeInt(1);
426 sound.writeToParcel(parcel, 0);
427 } else {
428 parcel.writeInt(0);
429 }
430 parcel.writeInt(audioStreamType);
431 parcel.writeLongArray(vibrate);
432 parcel.writeInt(ledARGB);
433 parcel.writeInt(ledOnMS);
434 parcel.writeInt(ledOffMS);
435 parcel.writeInt(iconLevel);
436 }
437
438 /**
439 * Parcelable.Creator that instantiates Notification objects
440 */
441 public static final Parcelable.Creator<Notification> CREATOR
442 = new Parcelable.Creator<Notification>()
443 {
444 public Notification createFromParcel(Parcel parcel)
445 {
446 return new Notification(parcel);
447 }
448
449 public Notification[] newArray(int size)
450 {
451 return new Notification[size];
452 }
453 };
454
455 /**
456 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
457 * layout.
458 *
459 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
460 * in the view.</p>
461 * @param context The context for your application / activity.
462 * @param contentTitle The title that goes in the expanded entry.
463 * @param contentText The text that goes in the expanded entry.
464 * @param contentIntent The intent to launch when the user clicks the expanded notification.
465 * If this is an activity, it must include the
466 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
467 * that you take care of task management as described in
468 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
469 */
470 public void setLatestEventInfo(Context context,
471 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
472 RemoteViews contentView = new RemoteViews(context.getPackageName(),
473 com.android.internal.R.layout.status_bar_latest_event_content);
474 if (this.icon != 0) {
475 contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
476 }
477 if (contentTitle != null) {
478 contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
479 }
480 if (contentText != null) {
481 contentView.setTextViewText(com.android.internal.R.id.text, contentText);
482 }
483 if (this.when != 0) {
Joe Onoratoc83bb732010-01-19 16:32:22 -0800484 contentView.setLong(com.android.internal.R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 }
486
487 this.contentView = contentView;
488 this.contentIntent = contentIntent;
489 }
490
491 @Override
492 public String toString() {
493 StringBuilder sb = new StringBuilder();
494 sb.append("Notification(vibrate=");
495 if (this.vibrate != null) {
496 int N = this.vibrate.length-1;
497 sb.append("[");
498 for (int i=0; i<N; i++) {
499 sb.append(this.vibrate[i]);
500 sb.append(',');
501 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200502 if (N != -1) {
503 sb.append(this.vibrate[N]);
504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 sb.append("]");
506 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
507 sb.append("default");
508 } else {
509 sb.append("null");
510 }
511 sb.append(",sound=");
512 if (this.sound != null) {
513 sb.append(this.sound.toString());
514 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
515 sb.append("default");
516 } else {
517 sb.append("null");
518 }
519 sb.append(",defaults=0x");
520 sb.append(Integer.toHexString(this.defaults));
521 sb.append(")");
522 return sb.toString();
523 }
524}