blob: 4370ebf93c281ca22167b12fde04e11709a7acb5 [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
Andy Stadler110988c2010-12-03 14:29:16 -080019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.Context;
22import android.content.Intent;
Joe Onoratoef1e7762010-09-17 18:38:38 -040023import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.net.Uri;
25import android.os.Parcel;
26import android.os.Parcelable;
27import android.text.TextUtils;
Joe Onorato8595a3d2010-11-19 18:12:07 -080028import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.widget.RemoteViews;
30
Andy Stadler110988c2010-12-03 14:29:16 -080031import java.text.NumberFormat;
Joe Onorato561d3852010-11-20 18:09:34 -080032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033/**
34 * A class that represents how a persistent notification is to be presented to
35 * the user using the {@link android.app.NotificationManager}.
36 *
Joe Onoratocb109a02011-01-18 17:57:41 -080037 * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
38 * easier to construct Notifications.</p>
39 *
Scott Mainb8b36452009-04-26 15:50:49 -070040 * <p>For a guide to creating notifications, see the
41 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
42 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 */
44public class Notification implements Parcelable
45{
46 /**
47 * Use all default values (where applicable).
48 */
49 public static final int DEFAULT_ALL = ~0;
50
51 /**
52 * Use the default notification sound. This will ignore any given
53 * {@link #sound}.
54 *
55 * @see #defaults
56 */
57 public static final int DEFAULT_SOUND = 1;
58
59 /**
60 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070061 * {@link #vibrate}. Using phone vibration requires the
62 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 *
64 * @see #defaults
65 */
66 public static final int DEFAULT_VIBRATE = 2;
67
68 /**
69 * Use the default notification lights. This will ignore the
70 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
71 * {@link #ledOnMS}.
72 *
73 * @see #defaults
74 */
75 public static final int DEFAULT_LIGHTS = 4;
76
77 /**
78 * The timestamp for the notification. The icons and expanded views
79 * are sorted by this key.
80 */
81 public long when;
82
83 /**
84 * The resource id of a drawable to use as the icon in the status bar.
85 */
86 public int icon;
87
88 /**
Joe Onorato46439ce2010-11-19 13:56:21 -080089 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
90 * leave it at its default value of 0.
91 *
92 * @see android.widget.ImageView#setImageLevel
93 * @see android.graphics.drawable#setLevel
94 */
95 public int iconLevel;
96
97 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -040098 * The number of events that this notification represents. For example, in a new mail
99 * notification, this could be the number of unread messages. This number is superimposed over
100 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
101 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 */
103 public int number;
104
105 /**
106 * The intent to execute when the expanded status entry is clicked. If
107 * this is an activity, it must include the
108 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800109 * that you take care of task management as described in the
110 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
111 * Stack</a> document.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 */
113 public PendingIntent contentIntent;
114
115 /**
116 * The intent to execute when the status entry is deleted by the user
117 * with the "Clear All Notifications" button. This probably shouldn't
118 * be launching an activity since several of those will be sent at the
119 * same time.
120 */
121 public PendingIntent deleteIntent;
122
123 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700124 * An intent to launch instead of posting the notification to the status bar.
Joe Onoratocb109a02011-01-18 17:57:41 -0800125 *
126 * @see Notification.Builder#setFullScreenIntent
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400127 */
128 public PendingIntent fullScreenIntent;
129
130 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400132 * the status bar on large and smaller devices.
133 *
134 * <p>This field is provided separately from the other ticker fields
135 * both for compatibility and to allow an application to choose different
136 * text for when the text scrolls in and when it is displayed all at once
137 * in conjunction with one or more icons.
138 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800139 * @see #tickerView
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 */
141 public CharSequence tickerText;
142
143 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800144 * The view to show as the ticker in the status bar when the notification
145 * is posted.
Joe Onoratoef1e7762010-09-17 18:38:38 -0400146 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800147 public RemoteViews tickerView;
Joe Onoratoef1e7762010-09-17 18:38:38 -0400148
149 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400150 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 */
152 public RemoteViews contentView;
153
154 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800155 * The bitmap that may escape the bounds of the panel and bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800157 public Bitmap largeIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158
159 /**
160 * The sound to play.
161 *
162 * <p>
163 * To play the default notification sound, see {@link #defaults}.
164 * </p>
165 */
166 public Uri sound;
167
168 /**
169 * Use this constant as the value for audioStreamType to request that
170 * the default stream type for notifications be used. Currently the
171 * default stream type is STREAM_RING.
172 */
173 public static final int STREAM_DEFAULT = -1;
174
175 /**
176 * The audio stream type to use when playing the sound.
177 * Should be one of the STREAM_ constants from
178 * {@link android.media.AudioManager}.
179 */
180 public int audioStreamType = STREAM_DEFAULT;
181
182
183 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700184 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 *
186 * <p>
187 * To vibrate the default pattern, see {@link #defaults}.
188 * </p>
189 *
190 * @see android.os.Vibrator#vibrate(long[],int)
191 */
192 public long[] vibrate;
193
194 /**
195 * The color of the led. The hardware will do its best approximation.
196 *
197 * @see #FLAG_SHOW_LIGHTS
198 * @see #flags
199 */
200 public int ledARGB;
201
202 /**
203 * The number of milliseconds for the LED to be on while it's flashing.
204 * The hardware will do its best approximation.
205 *
206 * @see #FLAG_SHOW_LIGHTS
207 * @see #flags
208 */
209 public int ledOnMS;
210
211 /**
212 * The number of milliseconds for the LED to be off while it's flashing.
213 * The hardware will do its best approximation.
214 *
215 * @see #FLAG_SHOW_LIGHTS
216 * @see #flags
217 */
218 public int ledOffMS;
219
220 /**
221 * Specifies which values should be taken from the defaults.
222 * <p>
223 * To set, OR the desired from {@link #DEFAULT_SOUND},
224 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
225 * values, use {@link #DEFAULT_ALL}.
226 * </p>
227 */
228 public int defaults;
229
230
231 /**
232 * Bit to be bitwise-ored into the {@link #flags} field that should be
233 * set if you want the LED on for this notification.
234 * <ul>
235 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
236 * or 0 for both ledOnMS and ledOffMS.</li>
237 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
238 * <li>To flash the LED, pass the number of milliseconds that it should
239 * be on and off to ledOnMS and ledOffMS.</li>
240 * </ul>
241 * <p>
242 * Since hardware varies, you are not guaranteed that any of the values
243 * you pass are honored exactly. Use the system defaults (TODO) if possible
244 * because they will be set to values that work on any given hardware.
245 * <p>
246 * The alpha channel must be set for forward compatibility.
247 *
248 */
249 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
250
251 /**
252 * Bit to be bitwise-ored into the {@link #flags} field that should be
253 * set if this notification is in reference to something that is ongoing,
254 * like a phone call. It should not be set if this notification is in
255 * reference to something that happened at a particular point in time,
256 * like a missed phone call.
257 */
258 public static final int FLAG_ONGOING_EVENT = 0x00000002;
259
260 /**
261 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700262 * the audio will be repeated until the notification is
263 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 */
265 public static final int FLAG_INSISTENT = 0x00000004;
266
267 /**
268 * Bit to be bitwise-ored into the {@link #flags} field that should be
269 * set if you want the sound and/or vibration play each time the
270 * notification is sent, even if it has not been canceled before that.
271 */
272 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
273
274 /**
275 * Bit to be bitwise-ored into the {@link #flags} field that should be
276 * set if the notification should be canceled when it is clicked by the
Joe Onoratocb109a02011-01-18 17:57:41 -0800277 * user. On tablets, the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 */
279 public static final int FLAG_AUTO_CANCEL = 0x00000010;
280
281 /**
282 * Bit to be bitwise-ored into the {@link #flags} field that should be
283 * set if the notification should not be canceled when the user clicks
284 * the Clear all button.
285 */
286 public static final int FLAG_NO_CLEAR = 0x00000020;
287
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700288 /**
289 * Bit to be bitwise-ored into the {@link #flags} field that should be
290 * set if this notification represents a currently running service. This
291 * will normally be set for you by {@link Service#startForeground}.
292 */
293 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
294
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400295 /**
296 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
297 * represents a high-priority event that may be shown to the user even if notifications are
298 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
299 * in conjunction with {@link #fullScreenIntent}.
300 */
301 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 public int flags;
304
305 /**
306 * Constructs a Notification object with everything set to 0.
Joe Onorato46439ce2010-11-19 13:56:21 -0800307 * You might want to consider using {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 */
309 public Notification()
310 {
311 this.when = System.currentTimeMillis();
312 }
313
314 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 * @hide
316 */
317 public Notification(Context context, int icon, CharSequence tickerText, long when,
318 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
319 {
320 this.when = when;
321 this.icon = icon;
322 this.tickerText = tickerText;
323 setLatestEventInfo(context, contentTitle, contentText,
324 PendingIntent.getActivity(context, 0, contentIntent, 0));
325 }
326
327 /**
328 * Constructs a Notification object with the information needed to
329 * have a status bar icon without the standard expanded view.
330 *
331 * @param icon The resource id of the icon to put in the status bar.
332 * @param tickerText The text that flows by in the status bar when the notification first
333 * activates.
334 * @param when The time to show in the time field. In the System.currentTimeMillis
335 * timebase.
Joe Onorato46439ce2010-11-19 13:56:21 -0800336 *
337 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800339 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 public Notification(int icon, CharSequence tickerText, long when)
341 {
342 this.icon = icon;
343 this.tickerText = tickerText;
344 this.when = when;
345 }
346
347 /**
348 * Unflatten the notification from a parcel.
349 */
350 public Notification(Parcel parcel)
351 {
352 int version = parcel.readInt();
353
354 when = parcel.readLong();
355 icon = parcel.readInt();
356 number = parcel.readInt();
357 if (parcel.readInt() != 0) {
358 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
359 }
360 if (parcel.readInt() != 0) {
361 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
362 }
363 if (parcel.readInt() != 0) {
364 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
365 }
366 if (parcel.readInt() != 0) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800367 tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400368 }
369 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
371 }
Joe Onorato561d3852010-11-20 18:09:34 -0800372 if (parcel.readInt() != 0) {
373 largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 defaults = parcel.readInt();
376 flags = parcel.readInt();
377 if (parcel.readInt() != 0) {
378 sound = Uri.CREATOR.createFromParcel(parcel);
379 }
380
381 audioStreamType = parcel.readInt();
382 vibrate = parcel.createLongArray();
383 ledARGB = parcel.readInt();
384 ledOnMS = parcel.readInt();
385 ledOffMS = parcel.readInt();
386 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400387
388 if (parcel.readInt() != 0) {
389 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392
Andy Stadler110988c2010-12-03 14:29:16 -0800393 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700394 public Notification clone() {
395 Notification that = new Notification();
396
397 that.when = this.when;
398 that.icon = this.icon;
399 that.number = this.number;
400
401 // PendingIntents are global, so there's no reason (or way) to clone them.
402 that.contentIntent = this.contentIntent;
403 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400404 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700405
406 if (this.tickerText != null) {
407 that.tickerText = this.tickerText.toString();
408 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800409 if (this.tickerView != null) {
410 that.tickerView = this.tickerView.clone();
Joe Onoratoef1e7762010-09-17 18:38:38 -0400411 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700412 if (this.contentView != null) {
413 that.contentView = this.contentView.clone();
414 }
Joe Onorato561d3852010-11-20 18:09:34 -0800415 if (this.largeIcon != null) {
416 that.largeIcon = Bitmap.createBitmap(this.largeIcon);
417 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700418 that.iconLevel = that.iconLevel;
419 that.sound = this.sound; // android.net.Uri is immutable
420 that.audioStreamType = this.audioStreamType;
421
422 final long[] vibrate = this.vibrate;
423 if (vibrate != null) {
424 final int N = vibrate.length;
425 final long[] vib = that.vibrate = new long[N];
426 System.arraycopy(vibrate, 0, vib, 0, N);
427 }
428
429 that.ledARGB = this.ledARGB;
430 that.ledOnMS = this.ledOnMS;
431 that.ledOffMS = this.ledOffMS;
432 that.defaults = this.defaults;
433
434 that.flags = this.flags;
435
436 return that;
437 }
438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 public int describeContents() {
440 return 0;
441 }
442
443 /**
444 * Flatten this notification from a parcel.
445 */
446 public void writeToParcel(Parcel parcel, int flags)
447 {
448 parcel.writeInt(1);
449
450 parcel.writeLong(when);
451 parcel.writeInt(icon);
452 parcel.writeInt(number);
453 if (contentIntent != null) {
454 parcel.writeInt(1);
455 contentIntent.writeToParcel(parcel, 0);
456 } else {
457 parcel.writeInt(0);
458 }
459 if (deleteIntent != null) {
460 parcel.writeInt(1);
461 deleteIntent.writeToParcel(parcel, 0);
462 } else {
463 parcel.writeInt(0);
464 }
465 if (tickerText != null) {
466 parcel.writeInt(1);
467 TextUtils.writeToParcel(tickerText, parcel, flags);
468 } else {
469 parcel.writeInt(0);
470 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800471 if (tickerView != null) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400472 parcel.writeInt(1);
Joe Onorato46439ce2010-11-19 13:56:21 -0800473 tickerView.writeToParcel(parcel, 0);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400474 } else {
475 parcel.writeInt(0);
476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 if (contentView != null) {
478 parcel.writeInt(1);
479 contentView.writeToParcel(parcel, 0);
480 } else {
481 parcel.writeInt(0);
482 }
Joe Onorato561d3852010-11-20 18:09:34 -0800483 if (largeIcon != null) {
484 parcel.writeInt(1);
485 largeIcon.writeToParcel(parcel, 0);
486 } else {
487 parcel.writeInt(0);
488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489
490 parcel.writeInt(defaults);
491 parcel.writeInt(this.flags);
492
493 if (sound != null) {
494 parcel.writeInt(1);
495 sound.writeToParcel(parcel, 0);
496 } else {
497 parcel.writeInt(0);
498 }
499 parcel.writeInt(audioStreamType);
500 parcel.writeLongArray(vibrate);
501 parcel.writeInt(ledARGB);
502 parcel.writeInt(ledOnMS);
503 parcel.writeInt(ledOffMS);
504 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400505
506 if (fullScreenIntent != null) {
507 parcel.writeInt(1);
508 fullScreenIntent.writeToParcel(parcel, 0);
509 } else {
510 parcel.writeInt(0);
511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 }
513
514 /**
515 * Parcelable.Creator that instantiates Notification objects
516 */
517 public static final Parcelable.Creator<Notification> CREATOR
518 = new Parcelable.Creator<Notification>()
519 {
520 public Notification createFromParcel(Parcel parcel)
521 {
522 return new Notification(parcel);
523 }
524
525 public Notification[] newArray(int size)
526 {
527 return new Notification[size];
528 }
529 };
530
531 /**
532 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
533 * layout.
534 *
535 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
536 * in the view.</p>
537 * @param context The context for your application / activity.
538 * @param contentTitle The title that goes in the expanded entry.
539 * @param contentText The text that goes in the expanded entry.
540 * @param contentIntent The intent to launch when the user clicks the expanded notification.
541 * If this is an activity, it must include the
542 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
Scott Main7aee61f2011-02-08 11:25:01 -0800543 * that you take care of task management as described in the
544 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
545 * Stack</a> document.
Joe Onorato46439ce2010-11-19 13:56:21 -0800546 *
547 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800549 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 public void setLatestEventInfo(Context context,
551 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
552 RemoteViews contentView = new RemoteViews(context.getPackageName(),
Joe Onorato561d3852010-11-20 18:09:34 -0800553 R.layout.status_bar_latest_event_content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 if (this.icon != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800555 contentView.setImageViewResource(R.id.icon, this.icon);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 }
557 if (contentTitle != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800558 contentView.setTextViewText(R.id.title, contentTitle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 }
560 if (contentText != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800561 contentView.setTextViewText(R.id.text, contentText);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
563 if (this.when != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800564 contentView.setLong(R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566
567 this.contentView = contentView;
568 this.contentIntent = contentIntent;
569 }
570
571 @Override
572 public String toString() {
573 StringBuilder sb = new StringBuilder();
Joe Onoratoc9596d62011-01-12 17:03:11 -0800574 sb.append("Notification(contentView=");
575 if (contentView != null) {
576 sb.append(contentView.getPackage());
577 sb.append("/0x");
578 sb.append(Integer.toHexString(contentView.getLayoutId()));
579 } else {
580 sb.append("null");
581 }
582 sb.append(" vibrate=");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 if (this.vibrate != null) {
584 int N = this.vibrate.length-1;
585 sb.append("[");
586 for (int i=0; i<N; i++) {
587 sb.append(this.vibrate[i]);
588 sb.append(',');
589 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200590 if (N != -1) {
591 sb.append(this.vibrate[N]);
592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 sb.append("]");
594 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
595 sb.append("default");
596 } else {
597 sb.append("null");
598 }
599 sb.append(",sound=");
600 if (this.sound != null) {
601 sb.append(this.sound.toString());
602 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
603 sb.append("default");
604 } else {
605 sb.append("null");
606 }
607 sb.append(",defaults=0x");
608 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400609 sb.append(",flags=0x");
610 sb.append(Integer.toHexString(this.flags));
611 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
612 sb.append("!!!1!one!");
613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 sb.append(")");
615 return sb.toString();
616 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800617
Joe Onoratocb109a02011-01-18 17:57:41 -0800618 /**
619 * Builder class for {@link Notification} objects. Allows easier control over
620 * all the flags, as well as help constructing the typical notification layouts.
621 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800622 public static class Builder {
623 private Context mContext;
624
625 private long mWhen;
626 private int mSmallIcon;
627 private int mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800628 private int mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800629 private CharSequence mContentTitle;
630 private CharSequence mContentText;
631 private CharSequence mContentInfo;
632 private PendingIntent mContentIntent;
633 private RemoteViews mContentView;
634 private PendingIntent mDeleteIntent;
635 private PendingIntent mFullScreenIntent;
636 private CharSequence mTickerText;
637 private RemoteViews mTickerView;
638 private Bitmap mLargeIcon;
639 private Uri mSound;
640 private int mAudioStreamType;
641 private long[] mVibrate;
642 private int mLedArgb;
643 private int mLedOnMs;
644 private int mLedOffMs;
645 private int mDefaults;
646 private int mFlags;
647
Joe Onoratocb109a02011-01-18 17:57:41 -0800648 /**
649 * Constructor.
650 *
651 * Automatically sets the when field to {@link System#currentTimeMillis()
652 * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
653 *
654 * @param context A {@link Context} that will be used to construct the
655 * RemoteViews. The Context will not be held past the lifetime of this
656 * Builder object.
657 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800658 public Builder(Context context) {
659 mContext = context;
Andy Stadler110988c2010-12-03 14:29:16 -0800660
661 // Set defaults to match the defaults of a Notification
Joe Onorato46439ce2010-11-19 13:56:21 -0800662 mWhen = System.currentTimeMillis();
Andy Stadler110988c2010-12-03 14:29:16 -0800663 mAudioStreamType = STREAM_DEFAULT;
Joe Onorato46439ce2010-11-19 13:56:21 -0800664 }
665
Joe Onoratocb109a02011-01-18 17:57:41 -0800666 /**
667 * Set the time that the event occurred. Notifications in the panel are
668 * sorted by this time.
669 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800670 public Builder setWhen(long when) {
671 mWhen = when;
672 return this;
673 }
674
Joe Onoratocb109a02011-01-18 17:57:41 -0800675 /**
676 * Set the small icon to use in the notification layouts. Different classes of devices
677 * may return different sizes. See the UX guidelines for more information on how to
678 * design these icons.
679 *
680 * @param icon A resource ID in the application's package of the drawble to use.
681 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800682 public Builder setSmallIcon(int icon) {
683 mSmallIcon = icon;
684 return this;
685 }
686
Joe Onoratocb109a02011-01-18 17:57:41 -0800687 /**
688 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
689 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
690 * LevelListDrawable}.
691 *
692 * @param icon A resource ID in the application's package of the drawble to use.
693 * @param level The level to use for the icon.
694 *
695 * @see android.graphics.drawable.LevelListDrawable
696 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800697 public Builder setSmallIcon(int icon, int level) {
698 mSmallIcon = icon;
699 mSmallIconLevel = level;
700 return this;
701 }
702
Joe Onoratocb109a02011-01-18 17:57:41 -0800703 /**
704 * Set the title (first row) of the notification, in a standard notification.
705 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800706 public Builder setContentTitle(CharSequence title) {
707 mContentTitle = title;
708 return this;
709 }
710
Joe Onoratocb109a02011-01-18 17:57:41 -0800711 /**
712 * Set the text (second row) of the notification, in a standard notification.
713 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800714 public Builder setContentText(CharSequence text) {
715 mContentText = text;
716 return this;
717 }
718
Joe Onoratocb109a02011-01-18 17:57:41 -0800719 /**
720 * Set the large number at the right-hand side of the notification. This is
721 * equivalent to setContentInfo, although it might show the number in a different
722 * font size for readability.
723 */
Joe Onorato8595a3d2010-11-19 18:12:07 -0800724 public Builder setNumber(int number) {
725 mNumber = number;
726 return this;
727 }
728
Joe Onoratocb109a02011-01-18 17:57:41 -0800729 /**
730 * Set the large text at the right-hand side of the notification.
731 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800732 public Builder setContentInfo(CharSequence info) {
733 mContentInfo = info;
734 return this;
735 }
736
Joe Onoratocb109a02011-01-18 17:57:41 -0800737 /**
738 * Supply a custom RemoteViews to use instead of the standard one.
739 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800740 public Builder setContent(RemoteViews views) {
741 mContentView = views;
742 return this;
743 }
744
Joe Onoratocb109a02011-01-18 17:57:41 -0800745 /**
746 * Supply a {@link PendingIntent} to send when the notification is clicked.
747 * If you do not supply an intent, you can now add PendingIntents to individual
748 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
749 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
750 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800751 public Builder setContentIntent(PendingIntent intent) {
752 mContentIntent = intent;
753 return this;
754 }
755
Joe Onoratocb109a02011-01-18 17:57:41 -0800756 /**
757 * Supply a {@link PendingIntent} to send when the notification is cleared by the user
758 * directly from the notification panel. For example, this intent is sent when the user
759 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
760 * intent is not sent when the application calls {@link NotificationManager#cancel
761 * NotificationManager.cancel(int)}.
762 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800763 public Builder setDeleteIntent(PendingIntent intent) {
764 mDeleteIntent = intent;
765 return this;
766 }
767
Joe Onoratocb109a02011-01-18 17:57:41 -0800768 /**
769 * An intent to launch instead of posting the notification to the status bar.
770 * Only for use with extremely high-priority notifications demanding the user's
771 * <strong>immediate</strong> attention, such as an incoming phone call or
772 * alarm clock that the user has explicitly set to a particular time.
773 * If this facility is used for something else, please give the user an option
774 * to turn it off and use a normal notification, as this can be extremely
775 * disruptive.
776 *
777 * @param intent The pending intent to launch.
778 * @param highPriority Passing true will cause this notification to be sent
779 * even if other notifications are suppressed.
780 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800781 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
782 mFullScreenIntent = intent;
783 setFlag(FLAG_HIGH_PRIORITY, highPriority);
784 return this;
785 }
786
Joe Onoratocb109a02011-01-18 17:57:41 -0800787 /**
788 * Set the text that is displayed in the status bar when the notification first
789 * arrives.
790 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800791 public Builder setTicker(CharSequence tickerText) {
792 mTickerText = tickerText;
793 return this;
794 }
795
Joe Onoratocb109a02011-01-18 17:57:41 -0800796 /**
797 * Set the text that is displayed in the status bar when the notification first
798 * arrives, and also a RemoteViews object that may be displayed instead on some
799 * devices.
800 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800801 public Builder setTicker(CharSequence tickerText, RemoteViews views) {
802 mTickerText = tickerText;
803 mTickerView = views;
804 return this;
805 }
806
Joe Onoratocb109a02011-01-18 17:57:41 -0800807 /**
808 * Set the large icon that is shown in the ticker and notification.
809 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800810 public Builder setLargeIcon(Bitmap icon) {
811 mLargeIcon = icon;
812 return this;
813 }
814
Joe Onoratocb109a02011-01-18 17:57:41 -0800815 /**
816 * Set the sound to play. It will play on the default stream.
817 */
Joe Onorato52f80cd2010-11-21 15:34:48 -0800818 public Builder setSound(Uri sound) {
819 mSound = sound;
820 mAudioStreamType = STREAM_DEFAULT;
821 return this;
822 }
823
Joe Onoratocb109a02011-01-18 17:57:41 -0800824 /**
825 * Set the sound to play. It will play on the stream you supply.
826 *
827 * @see #STREAM_DEFAULT
828 * @see AudioManager for the <code>STREAM_</code> constants.
829 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800830 public Builder setSound(Uri sound, int streamType) {
831 mSound = sound;
832 mAudioStreamType = streamType;
833 return this;
834 }
835
Joe Onoratocb109a02011-01-18 17:57:41 -0800836 /**
837 * Set the vibration pattern to use.
838 *
839 * @see android.os.Vibrator for a discussion of the <code>pattern</code>
840 * parameter.
841 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800842 public Builder setVibrate(long[] pattern) {
843 mVibrate = pattern;
844 return this;
845 }
846
Joe Onoratocb109a02011-01-18 17:57:41 -0800847 /**
848 * Set the argb value that you would like the LED on the device to blnk, as well as the
849 * rate. The rate is specified in terms of the number of milliseconds to be on
850 * and then the number of milliseconds to be off.
851 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800852 public Builder setLights(int argb, int onMs, int offMs) {
853 mLedArgb = argb;
854 mLedOnMs = onMs;
855 mLedOffMs = offMs;
Joe Onorato46439ce2010-11-19 13:56:21 -0800856 return this;
857 }
858
Joe Onoratocb109a02011-01-18 17:57:41 -0800859 /**
860 * Set whether this is an ongoing notification.
861 *
862 * <p>Ongoing notifications differ from regular notifications in the following ways:
863 * <ul>
864 * <li>Ongoing notifications are sorted above the regular notifications in the
865 * notification panel.</li>
866 * <li>Ongoing notifications do not have an 'X' close button, and are not affected
867 * by the "Clear all" button.
868 * </ul>
869 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800870 public Builder setOngoing(boolean ongoing) {
871 setFlag(FLAG_ONGOING_EVENT, ongoing);
872 return this;
873 }
874
Joe Onoratocb109a02011-01-18 17:57:41 -0800875 /**
876 * Set this flag if you would only like the sound, vibrate
877 * and ticker to be played if the notification is not already showing.
878 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800879 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
880 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
881 return this;
882 }
883
Joe Onoratocb109a02011-01-18 17:57:41 -0800884 /**
885 * Setting this flag will make it so the notification is automatically
886 * canceled when the user clicks it in the panel. The PendingIntent
887 * set with {@link #setDeleteIntent} will be broadcast when the notification
888 * is canceled.
889 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800890 public Builder setAutoCancel(boolean autoCancel) {
Joe Onorato281d83f2011-01-04 17:13:10 -0800891 setFlag(FLAG_AUTO_CANCEL, autoCancel);
Joe Onorato46439ce2010-11-19 13:56:21 -0800892 return this;
893 }
894
Joe Onoratocb109a02011-01-18 17:57:41 -0800895 /**
896 * Set the default notification options that will be used.
897 * <p>
898 * The value should be one or more of the following fields combined with
899 * bitwise-or:
900 * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
901 * <p>
902 * For all default values, use {@link #DEFAULT_ALL}.
903 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800904 public Builder setDefaults(int defaults) {
905 mDefaults = defaults;
906 return this;
907 }
908
909 private void setFlag(int mask, boolean value) {
910 if (value) {
911 mFlags |= mask;
912 } else {
913 mFlags &= ~mask;
914 }
915 }
916
Joe Onorato561d3852010-11-20 18:09:34 -0800917 private RemoteViews makeRemoteViews(int resId) {
918 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
919 if (mSmallIcon != 0) {
920 contentView.setImageViewResource(R.id.icon, mSmallIcon);
921 }
922 if (mContentTitle != null) {
923 contentView.setTextViewText(R.id.title, mContentTitle);
924 }
925 if (mContentText != null) {
926 contentView.setTextViewText(R.id.text, mContentText);
927 }
928 if (mContentInfo != null) {
929 contentView.setTextViewText(R.id.info, mContentInfo);
930 } else if (mNumber > 0) {
Joe Onoratoc6925ca2011-01-28 16:53:13 -0800931 if (mNumber > 999) {
932 contentView.setTextViewText(R.id.info, "999+");
Joe Onorato059a2f82011-01-04 10:27:01 -0800933 } else {
934 NumberFormat f = NumberFormat.getIntegerInstance();
935 contentView.setTextViewText(R.id.info, f.format(mNumber));
936 }
Joe Onorato561d3852010-11-20 18:09:34 -0800937 contentView.setFloat(R.id.info, "setTextSize",
938 mContext.getResources().getDimensionPixelSize(
939 R.dimen.status_bar_content_number_size));
940 } else {
941 contentView.setViewVisibility(R.id.info, View.GONE);
942 }
943 if (mWhen != 0) {
944 contentView.setLong(R.id.time, "setTime", mWhen);
945 }
946 return contentView;
947 }
948
Joe Onorato46439ce2010-11-19 13:56:21 -0800949 private RemoteViews makeContentView() {
950 if (mContentView != null) {
951 return mContentView;
952 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800953 return makeRemoteViews(mLargeIcon == null
954 ? R.layout.status_bar_latest_event_content
955 : R.layout.status_bar_latest_event_content_large_icon);
Joe Onorato46439ce2010-11-19 13:56:21 -0800956 }
957 }
958
959 private RemoteViews makeTickerView() {
960 if (mTickerView != null) {
961 return mTickerView;
962 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800963 if (mContentView == null) {
964 return makeRemoteViews(mLargeIcon == null
965 ? R.layout.status_bar_latest_event_ticker
966 : R.layout.status_bar_latest_event_ticker_large_icon);
967 } else {
968 return null;
969 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800970 }
971 }
972
Joe Onoratocb109a02011-01-18 17:57:41 -0800973 /**
974 * Combine all of the options that have been set and return a new {@link Notification}
975 * object.
976 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800977 public Notification getNotification() {
978 Notification n = new Notification();
979 n.when = mWhen;
980 n.icon = mSmallIcon;
981 n.iconLevel = mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800982 n.number = mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800983 n.contentView = makeContentView();
984 n.contentIntent = mContentIntent;
985 n.deleteIntent = mDeleteIntent;
986 n.fullScreenIntent = mFullScreenIntent;
987 n.tickerText = mTickerText;
988 n.tickerView = makeTickerView();
989 n.largeIcon = mLargeIcon;
990 n.sound = mSound;
991 n.audioStreamType = mAudioStreamType;
992 n.vibrate = mVibrate;
993 n.ledARGB = mLedArgb;
994 n.ledOnMS = mLedOnMs;
995 n.ledOffMS = mLedOffMs;
996 n.defaults = mDefaults;
997 n.flags = mFlags;
Joe Onorato8d0b6552010-11-22 16:09:29 -0800998 if (mLedOnMs != 0 && mLedOffMs != 0) {
999 n.flags |= FLAG_SHOW_LIGHTS;
1000 }
1001 if ((mDefaults & DEFAULT_LIGHTS) != 0) {
1002 n.flags |= FLAG_SHOW_LIGHTS;
1003 }
Joe Onorato46439ce2010-11-19 13:56:21 -08001004 return n;
1005 }
1006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007}