blob: 414a2a1afb785e3a8c940994780623d775e9141d [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 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -040086 * 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.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 */
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 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700112 * 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
Dianne Hackborn392fea52010-09-09 16:44:01 -0700114 * <strong>immediate</strong> attention, such as an incoming phone call or
Dianne Hackborn170bae72010-09-03 15:14:28 -0700115 * alarm clock that the user has explicitly set to a particular time.
Dianne Hackborn170bae72010-09-03 15:14:28 -0700116 * 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.
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400119 */
120 public PendingIntent fullScreenIntent;
121
122 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 * Text to scroll across the screen when this item is added to
124 * the status bar.
125 */
126 public CharSequence tickerText;
127
128 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400129 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 */
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 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700167 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 *
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,
Scott Mainb8b36452009-04-26 15:50:49 -0700245 * the audio will be repeated until the notification is
246 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 */
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
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700271 /**
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 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();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400353
354 if (parcel.readInt() != 0) {
355 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 }
358
Joe Onorato18e69df2010-05-17 22:26:12 -0700359 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;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400369 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700370
371 if (this.tickerText != null) {
372 that.tickerText = this.tickerText.toString();
373 }
374 if (this.contentView != null) {
375 that.contentView = this.contentView.clone();
376 }
Jozef BABJAKa8b91832011-02-22 08:05:08 +0100377 that.iconLevel = this.iconLevel;
Joe Onorato18e69df2010-05-17 22:26:12 -0700378 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 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);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400452
453 if (fullScreenIntent != null) {
454 parcel.writeInt(1);
455 fullScreenIntent.writeToParcel(parcel, 0);
456 } else {
457 parcel.writeInt(0);
458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 }
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) {
Joe Onoratoc83bb732010-01-19 16:32:22 -0800507 contentView.setLong(com.android.internal.R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 }
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 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200525 if (N != -1) {
526 sb.append(this.vibrate[N]);
527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 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));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400544 sb.append(",flags=0x");
545 sb.append(Integer.toHexString(this.flags));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 sb.append(")");
547 return sb.toString();
548 }
549}