blob: 920e4575bf1e42101fa1ef4b24ea7e0759769329 [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
Joe Onorato8595a3d2010-11-19 18:12:07 -080019import java.text.NumberFormat;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import java.util.Date;
21
22import android.app.PendingIntent;
23import android.content.Context;
24import android.content.Intent;
Joe Onoratoef1e7762010-09-17 18:38:38 -040025import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.media.AudioManager;
27import android.net.Uri;
28import android.os.Parcel;
29import android.os.Parcelable;
30import android.text.TextUtils;
31import android.text.format.DateFormat;
32import android.text.format.DateUtils;
Joe Onorato46439ce2010-11-19 13:56:21 -080033import android.util.Slog;
Joe Onorato8595a3d2010-11-19 18:12:07 -080034import android.view.View;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.widget.RemoteViews;
36
Joe Onorato561d3852010-11-20 18:09:34 -080037import com.android.internal.R;
38
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039/**
40 * A class that represents how a persistent notification is to be presented to
41 * the user using the {@link android.app.NotificationManager}.
42 *
Scott Mainb8b36452009-04-26 15:50:49 -070043 * <p>For a guide to creating notifications, see the
44 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
45 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 */
47public class Notification implements Parcelable
48{
Joe Onorato46439ce2010-11-19 13:56:21 -080049 private static final String TAG = "Notification";
50
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 /**
52 * Use all default values (where applicable).
53 */
54 public static final int DEFAULT_ALL = ~0;
55
56 /**
57 * Use the default notification sound. This will ignore any given
58 * {@link #sound}.
59 *
60 * @see #defaults
61 */
62 public static final int DEFAULT_SOUND = 1;
63
64 /**
65 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070066 * {@link #vibrate}. Using phone vibration requires the
67 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 *
69 * @see #defaults
70 */
71 public static final int DEFAULT_VIBRATE = 2;
72
73 /**
74 * Use the default notification lights. This will ignore the
75 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
76 * {@link #ledOnMS}.
77 *
78 * @see #defaults
79 */
80 public static final int DEFAULT_LIGHTS = 4;
81
82 /**
83 * The timestamp for the notification. The icons and expanded views
84 * are sorted by this key.
85 */
86 public long when;
87
88 /**
89 * The resource id of a drawable to use as the icon in the status bar.
90 */
91 public int icon;
92
93 /**
Joe Onorato46439ce2010-11-19 13:56:21 -080094 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
95 * leave it at its default value of 0.
96 *
97 * @see android.widget.ImageView#setImageLevel
98 * @see android.graphics.drawable#setLevel
99 */
100 public int iconLevel;
101
102 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400103 * The number of events that this notification represents. For example, in a new mail
104 * notification, this could be the number of unread messages. This number is superimposed over
105 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
106 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 */
108 public int number;
109
110 /**
111 * The intent to execute when the expanded status entry is clicked. If
112 * this is an activity, it must include the
113 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
114 * that you take care of task management as described in the <em>Activities and Tasks</em>
115 * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application
116 * Fundamentals</a> document.
117 */
118 public PendingIntent contentIntent;
119
120 /**
121 * The intent to execute when the status entry is deleted by the user
122 * with the "Clear All Notifications" button. This probably shouldn't
123 * be launching an activity since several of those will be sent at the
124 * same time.
125 */
126 public PendingIntent deleteIntent;
127
128 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700129 * An intent to launch instead of posting the notification to the status bar.
130 * Only for use with extremely high-priority notifications demanding the user's
Dianne Hackborn392fea52010-09-09 16:44:01 -0700131 * <strong>immediate</strong> attention, such as an incoming phone call or
Dianne Hackborn170bae72010-09-03 15:14:28 -0700132 * alarm clock that the user has explicitly set to a particular time.
Dianne Hackborn170bae72010-09-03 15:14:28 -0700133 * If this facility is used for something else, please give the user an option
134 * to turn it off and use a normal notification, as this can be extremely
135 * disruptive.
Dianne Hackborn61714012010-09-03 16:40:58 -0700136 *
137 * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
138 * will reach the user even when other notifications are suppressed.
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400139 */
140 public PendingIntent fullScreenIntent;
141
142 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400144 * the status bar on large and smaller devices.
145 *
146 * <p>This field is provided separately from the other ticker fields
147 * both for compatibility and to allow an application to choose different
148 * text for when the text scrolls in and when it is displayed all at once
149 * in conjunction with one or more icons.
150 *
Joe Onorato46439ce2010-11-19 13:56:21 -0800151 * @see #tickerView
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 */
153 public CharSequence tickerText;
154
155 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800156 * The view to show as the ticker in the status bar when the notification
157 * is posted.
Joe Onoratoef1e7762010-09-17 18:38:38 -0400158 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800159 public RemoteViews tickerView;
Joe Onoratoef1e7762010-09-17 18:38:38 -0400160
161 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400162 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 */
164 public RemoteViews contentView;
165
166 /**
Joe Onorato46439ce2010-11-19 13:56:21 -0800167 * The bitmap that may escape the bounds of the panel and bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800169 public Bitmap largeIcon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
171 /**
172 * The sound to play.
173 *
174 * <p>
175 * To play the default notification sound, see {@link #defaults}.
176 * </p>
177 */
178 public Uri sound;
179
180 /**
181 * Use this constant as the value for audioStreamType to request that
182 * the default stream type for notifications be used. Currently the
183 * default stream type is STREAM_RING.
184 */
185 public static final int STREAM_DEFAULT = -1;
186
187 /**
188 * The audio stream type to use when playing the sound.
189 * Should be one of the STREAM_ constants from
190 * {@link android.media.AudioManager}.
191 */
192 public int audioStreamType = STREAM_DEFAULT;
193
194
195 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700196 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 *
198 * <p>
199 * To vibrate the default pattern, see {@link #defaults}.
200 * </p>
201 *
202 * @see android.os.Vibrator#vibrate(long[],int)
203 */
204 public long[] vibrate;
205
206 /**
207 * The color of the led. The hardware will do its best approximation.
208 *
209 * @see #FLAG_SHOW_LIGHTS
210 * @see #flags
211 */
212 public int ledARGB;
213
214 /**
215 * The number of milliseconds for the LED to be on while it's flashing.
216 * The hardware will do its best approximation.
217 *
218 * @see #FLAG_SHOW_LIGHTS
219 * @see #flags
220 */
221 public int ledOnMS;
222
223 /**
224 * The number of milliseconds for the LED to be off while it's flashing.
225 * The hardware will do its best approximation.
226 *
227 * @see #FLAG_SHOW_LIGHTS
228 * @see #flags
229 */
230 public int ledOffMS;
231
232 /**
233 * Specifies which values should be taken from the defaults.
234 * <p>
235 * To set, OR the desired from {@link #DEFAULT_SOUND},
236 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
237 * values, use {@link #DEFAULT_ALL}.
238 * </p>
239 */
240 public int defaults;
241
242
243 /**
244 * Bit to be bitwise-ored into the {@link #flags} field that should be
245 * set if you want the LED on for this notification.
246 * <ul>
247 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
248 * or 0 for both ledOnMS and ledOffMS.</li>
249 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
250 * <li>To flash the LED, pass the number of milliseconds that it should
251 * be on and off to ledOnMS and ledOffMS.</li>
252 * </ul>
253 * <p>
254 * Since hardware varies, you are not guaranteed that any of the values
255 * you pass are honored exactly. Use the system defaults (TODO) if possible
256 * because they will be set to values that work on any given hardware.
257 * <p>
258 * The alpha channel must be set for forward compatibility.
259 *
260 */
261 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
262
263 /**
264 * Bit to be bitwise-ored into the {@link #flags} field that should be
265 * set if this notification is in reference to something that is ongoing,
266 * like a phone call. It should not be set if this notification is in
267 * reference to something that happened at a particular point in time,
268 * like a missed phone call.
269 */
270 public static final int FLAG_ONGOING_EVENT = 0x00000002;
271
272 /**
273 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700274 * the audio will be repeated until the notification is
275 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 */
277 public static final int FLAG_INSISTENT = 0x00000004;
278
279 /**
280 * Bit to be bitwise-ored into the {@link #flags} field that should be
281 * set if you want the sound and/or vibration play each time the
282 * notification is sent, even if it has not been canceled before that.
283 */
284 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
285
286 /**
287 * Bit to be bitwise-ored into the {@link #flags} field that should be
288 * set if the notification should be canceled when it is clicked by the
289 * user.
290 */
291 public static final int FLAG_AUTO_CANCEL = 0x00000010;
292
293 /**
294 * Bit to be bitwise-ored into the {@link #flags} field that should be
295 * set if the notification should not be canceled when the user clicks
296 * the Clear all button.
297 */
298 public static final int FLAG_NO_CLEAR = 0x00000020;
299
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700300 /**
301 * Bit to be bitwise-ored into the {@link #flags} field that should be
302 * set if this notification represents a currently running service. This
303 * will normally be set for you by {@link Service#startForeground}.
304 */
305 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
306
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400307 /**
308 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
309 * represents a high-priority event that may be shown to the user even if notifications are
310 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
311 * in conjunction with {@link #fullScreenIntent}.
312 */
313 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 public int flags;
316
317 /**
318 * Constructs a Notification object with everything set to 0.
Joe Onorato46439ce2010-11-19 13:56:21 -0800319 * You might want to consider using {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 */
321 public Notification()
322 {
323 this.when = System.currentTimeMillis();
324 }
325
326 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 * @hide
328 */
329 public Notification(Context context, int icon, CharSequence tickerText, long when,
330 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
331 {
332 this.when = when;
333 this.icon = icon;
334 this.tickerText = tickerText;
335 setLatestEventInfo(context, contentTitle, contentText,
336 PendingIntent.getActivity(context, 0, contentIntent, 0));
337 }
338
339 /**
340 * Constructs a Notification object with the information needed to
341 * have a status bar icon without the standard expanded view.
342 *
343 * @param icon The resource id of the icon to put in the status bar.
344 * @param tickerText The text that flows by in the status bar when the notification first
345 * activates.
346 * @param when The time to show in the time field. In the System.currentTimeMillis
347 * timebase.
Joe Onorato46439ce2010-11-19 13:56:21 -0800348 *
349 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800351 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 public Notification(int icon, CharSequence tickerText, long when)
353 {
354 this.icon = icon;
355 this.tickerText = tickerText;
356 this.when = when;
357 }
358
359 /**
360 * Unflatten the notification from a parcel.
361 */
362 public Notification(Parcel parcel)
363 {
364 int version = parcel.readInt();
365
366 when = parcel.readLong();
367 icon = parcel.readInt();
368 number = parcel.readInt();
369 if (parcel.readInt() != 0) {
370 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
371 }
372 if (parcel.readInt() != 0) {
373 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
374 }
375 if (parcel.readInt() != 0) {
376 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
377 }
378 if (parcel.readInt() != 0) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800379 tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400380 }
381 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
383 }
Joe Onorato561d3852010-11-20 18:09:34 -0800384 if (parcel.readInt() != 0) {
385 largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 defaults = parcel.readInt();
388 flags = parcel.readInt();
389 if (parcel.readInt() != 0) {
390 sound = Uri.CREATOR.createFromParcel(parcel);
391 }
392
393 audioStreamType = parcel.readInt();
394 vibrate = parcel.createLongArray();
395 ledARGB = parcel.readInt();
396 ledOnMS = parcel.readInt();
397 ledOffMS = parcel.readInt();
398 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400399
400 if (parcel.readInt() != 0) {
401 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404
Joe Onorato18e69df2010-05-17 22:26:12 -0700405 public Notification clone() {
406 Notification that = new Notification();
407
408 that.when = this.when;
409 that.icon = this.icon;
410 that.number = this.number;
411
412 // PendingIntents are global, so there's no reason (or way) to clone them.
413 that.contentIntent = this.contentIntent;
414 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400415 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700416
417 if (this.tickerText != null) {
418 that.tickerText = this.tickerText.toString();
419 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800420 if (this.tickerView != null) {
421 that.tickerView = this.tickerView.clone();
Joe Onoratoef1e7762010-09-17 18:38:38 -0400422 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700423 if (this.contentView != null) {
424 that.contentView = this.contentView.clone();
425 }
Joe Onorato561d3852010-11-20 18:09:34 -0800426 if (this.largeIcon != null) {
427 that.largeIcon = Bitmap.createBitmap(this.largeIcon);
428 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700429 that.iconLevel = that.iconLevel;
430 that.sound = this.sound; // android.net.Uri is immutable
431 that.audioStreamType = this.audioStreamType;
432
433 final long[] vibrate = this.vibrate;
434 if (vibrate != null) {
435 final int N = vibrate.length;
436 final long[] vib = that.vibrate = new long[N];
437 System.arraycopy(vibrate, 0, vib, 0, N);
438 }
439
440 that.ledARGB = this.ledARGB;
441 that.ledOnMS = this.ledOnMS;
442 that.ledOffMS = this.ledOffMS;
443 that.defaults = this.defaults;
444
445 that.flags = this.flags;
446
447 return that;
448 }
449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 public int describeContents() {
451 return 0;
452 }
453
454 /**
455 * Flatten this notification from a parcel.
456 */
457 public void writeToParcel(Parcel parcel, int flags)
458 {
459 parcel.writeInt(1);
460
461 parcel.writeLong(when);
462 parcel.writeInt(icon);
463 parcel.writeInt(number);
464 if (contentIntent != null) {
465 parcel.writeInt(1);
466 contentIntent.writeToParcel(parcel, 0);
467 } else {
468 parcel.writeInt(0);
469 }
470 if (deleteIntent != null) {
471 parcel.writeInt(1);
472 deleteIntent.writeToParcel(parcel, 0);
473 } else {
474 parcel.writeInt(0);
475 }
476 if (tickerText != null) {
477 parcel.writeInt(1);
478 TextUtils.writeToParcel(tickerText, parcel, flags);
479 } else {
480 parcel.writeInt(0);
481 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800482 if (tickerView != null) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400483 parcel.writeInt(1);
Joe Onorato46439ce2010-11-19 13:56:21 -0800484 tickerView.writeToParcel(parcel, 0);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400485 } else {
486 parcel.writeInt(0);
487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 if (contentView != null) {
489 parcel.writeInt(1);
490 contentView.writeToParcel(parcel, 0);
491 } else {
492 parcel.writeInt(0);
493 }
Joe Onorato561d3852010-11-20 18:09:34 -0800494 if (largeIcon != null) {
495 parcel.writeInt(1);
496 largeIcon.writeToParcel(parcel, 0);
497 } else {
498 parcel.writeInt(0);
499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500
501 parcel.writeInt(defaults);
502 parcel.writeInt(this.flags);
503
504 if (sound != null) {
505 parcel.writeInt(1);
506 sound.writeToParcel(parcel, 0);
507 } else {
508 parcel.writeInt(0);
509 }
510 parcel.writeInt(audioStreamType);
511 parcel.writeLongArray(vibrate);
512 parcel.writeInt(ledARGB);
513 parcel.writeInt(ledOnMS);
514 parcel.writeInt(ledOffMS);
515 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400516
517 if (fullScreenIntent != null) {
518 parcel.writeInt(1);
519 fullScreenIntent.writeToParcel(parcel, 0);
520 } else {
521 parcel.writeInt(0);
522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 }
524
525 /**
526 * Parcelable.Creator that instantiates Notification objects
527 */
528 public static final Parcelable.Creator<Notification> CREATOR
529 = new Parcelable.Creator<Notification>()
530 {
531 public Notification createFromParcel(Parcel parcel)
532 {
533 return new Notification(parcel);
534 }
535
536 public Notification[] newArray(int size)
537 {
538 return new Notification[size];
539 }
540 };
541
542 /**
543 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
544 * layout.
545 *
546 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
547 * in the view.</p>
548 * @param context The context for your application / activity.
549 * @param contentTitle The title that goes in the expanded entry.
550 * @param contentText The text that goes in the expanded entry.
551 * @param contentIntent The intent to launch when the user clicks the expanded notification.
552 * If this is an activity, it must include the
553 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
554 * that you take care of task management as described in
555 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
Joe Onorato46439ce2010-11-19 13:56:21 -0800556 *
557 * @deprecated Use {@link Builder} instead.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 */
Joe Onorato46439ce2010-11-19 13:56:21 -0800559 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 public void setLatestEventInfo(Context context,
561 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
562 RemoteViews contentView = new RemoteViews(context.getPackageName(),
Joe Onorato561d3852010-11-20 18:09:34 -0800563 R.layout.status_bar_latest_event_content);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 if (this.icon != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800565 contentView.setImageViewResource(R.id.icon, this.icon);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800566 }
567 if (contentTitle != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800568 contentView.setTextViewText(R.id.title, contentTitle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 }
570 if (contentText != null) {
Joe Onorato561d3852010-11-20 18:09:34 -0800571 contentView.setTextViewText(R.id.text, contentText);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 }
573 if (this.when != 0) {
Joe Onorato561d3852010-11-20 18:09:34 -0800574 contentView.setLong(R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 }
576
577 this.contentView = contentView;
578 this.contentIntent = contentIntent;
579 }
580
581 @Override
582 public String toString() {
583 StringBuilder sb = new StringBuilder();
584 sb.append("Notification(vibrate=");
585 if (this.vibrate != null) {
586 int N = this.vibrate.length-1;
587 sb.append("[");
588 for (int i=0; i<N; i++) {
589 sb.append(this.vibrate[i]);
590 sb.append(',');
591 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200592 if (N != -1) {
593 sb.append(this.vibrate[N]);
594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 sb.append("]");
596 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
597 sb.append("default");
598 } else {
599 sb.append("null");
600 }
601 sb.append(",sound=");
602 if (this.sound != null) {
603 sb.append(this.sound.toString());
604 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
605 sb.append("default");
606 } else {
607 sb.append("null");
608 }
609 sb.append(",defaults=0x");
610 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400611 sb.append(",flags=0x");
612 sb.append(Integer.toHexString(this.flags));
613 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
614 sb.append("!!!1!one!");
615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 sb.append(")");
617 return sb.toString();
618 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800619
620 public static class Builder {
621 private Context mContext;
622
623 private long mWhen;
624 private int mSmallIcon;
625 private int mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800626 private int mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800627 private CharSequence mContentTitle;
628 private CharSequence mContentText;
629 private CharSequence mContentInfo;
630 private PendingIntent mContentIntent;
631 private RemoteViews mContentView;
632 private PendingIntent mDeleteIntent;
633 private PendingIntent mFullScreenIntent;
634 private CharSequence mTickerText;
635 private RemoteViews mTickerView;
636 private Bitmap mLargeIcon;
637 private Uri mSound;
638 private int mAudioStreamType;
639 private long[] mVibrate;
640 private int mLedArgb;
641 private int mLedOnMs;
642 private int mLedOffMs;
643 private int mDefaults;
644 private int mFlags;
645
646 public Builder(Context context) {
647 mContext = context;
648 mWhen = System.currentTimeMillis();
649 }
650
651 public Builder setWhen(long when) {
652 mWhen = when;
653 return this;
654 }
655
656 public Builder setSmallIcon(int icon) {
657 mSmallIcon = icon;
658 return this;
659 }
660
661 public Builder setSmallIcon(int icon, int level) {
662 mSmallIcon = icon;
663 mSmallIconLevel = level;
664 return this;
665 }
666
Joe Onorato46439ce2010-11-19 13:56:21 -0800667 public Builder setContentTitle(CharSequence title) {
668 mContentTitle = title;
669 return this;
670 }
671
672 public Builder setContentText(CharSequence text) {
673 mContentText = text;
674 return this;
675 }
676
Joe Onorato8595a3d2010-11-19 18:12:07 -0800677 public Builder setNumber(int number) {
678 mNumber = number;
679 return this;
680 }
681
Joe Onorato46439ce2010-11-19 13:56:21 -0800682 public Builder setContentInfo(CharSequence info) {
683 mContentInfo = info;
684 return this;
685 }
686
687 public Builder setContent(RemoteViews views) {
688 mContentView = views;
689 return this;
690 }
691
692 public Builder setContentIntent(PendingIntent intent) {
693 mContentIntent = intent;
694 return this;
695 }
696
697 public Builder setDeleteIntent(PendingIntent intent) {
698 mDeleteIntent = intent;
699 return this;
700 }
701
702 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
703 mFullScreenIntent = intent;
704 setFlag(FLAG_HIGH_PRIORITY, highPriority);
705 return this;
706 }
707
708 public Builder setTicker(CharSequence tickerText) {
709 mTickerText = tickerText;
710 return this;
711 }
712
713 public Builder setTicker(CharSequence tickerText, RemoteViews views) {
714 mTickerText = tickerText;
715 mTickerView = views;
716 return this;
717 }
718
719 public Builder setLargeIcon(Bitmap icon) {
720 mLargeIcon = icon;
721 return this;
722 }
723
Joe Onorato52f80cd2010-11-21 15:34:48 -0800724 public Builder setSound(Uri sound) {
725 mSound = sound;
726 mAudioStreamType = STREAM_DEFAULT;
727 return this;
728 }
729
Joe Onorato46439ce2010-11-19 13:56:21 -0800730 public Builder setSound(Uri sound, int streamType) {
731 mSound = sound;
732 mAudioStreamType = streamType;
733 return this;
734 }
735
736 public Builder setVibrate(long[] pattern) {
737 mVibrate = pattern;
738 return this;
739 }
740
741 public Builder setLights(int argb, int onMs, int offMs) {
742 mLedArgb = argb;
743 mLedOnMs = onMs;
744 mLedOffMs = offMs;
745 mFlags |= FLAG_SHOW_LIGHTS;
746 return this;
747 }
748
749 public Builder setOngoing(boolean ongoing) {
750 setFlag(FLAG_ONGOING_EVENT, ongoing);
751 return this;
752 }
753
754 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
755 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
756 return this;
757 }
758
759 public Builder setAutoCancel(boolean autoCancel) {
760 setFlag(FLAG_ONLY_ALERT_ONCE, autoCancel);
761 return this;
762 }
763
764 public Builder setDefaults(int defaults) {
765 mDefaults = defaults;
Joe Onorato52f80cd2010-11-21 15:34:48 -0800766 int moreFlags = 0;
767 if ((defaults & DEFAULT_LIGHTS) != 0) {
768 moreFlags |= FLAG_SHOW_LIGHTS;
769 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800770 return this;
771 }
772
773 private void setFlag(int mask, boolean value) {
774 if (value) {
775 mFlags |= mask;
776 } else {
777 mFlags &= ~mask;
778 }
779 }
780
Joe Onorato561d3852010-11-20 18:09:34 -0800781 private RemoteViews makeRemoteViews(int resId) {
782 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
783 if (mSmallIcon != 0) {
784 contentView.setImageViewResource(R.id.icon, mSmallIcon);
785 }
786 if (mContentTitle != null) {
787 contentView.setTextViewText(R.id.title, mContentTitle);
788 }
789 if (mContentText != null) {
790 contentView.setTextViewText(R.id.text, mContentText);
791 }
792 if (mContentInfo != null) {
793 contentView.setTextViewText(R.id.info, mContentInfo);
794 } else if (mNumber > 0) {
795 NumberFormat f = NumberFormat.getIntegerInstance();
796 contentView.setTextViewText(R.id.info, f.format(mNumber));
797 contentView.setFloat(R.id.info, "setTextSize",
798 mContext.getResources().getDimensionPixelSize(
799 R.dimen.status_bar_content_number_size));
800 } else {
801 contentView.setViewVisibility(R.id.info, View.GONE);
802 }
803 if (mWhen != 0) {
804 contentView.setLong(R.id.time, "setTime", mWhen);
805 }
806 return contentView;
807 }
808
Joe Onorato46439ce2010-11-19 13:56:21 -0800809 private RemoteViews makeContentView() {
810 if (mContentView != null) {
811 return mContentView;
812 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800813 return makeRemoteViews(mLargeIcon == null
814 ? R.layout.status_bar_latest_event_content
815 : R.layout.status_bar_latest_event_content_large_icon);
Joe Onorato46439ce2010-11-19 13:56:21 -0800816 }
817 }
818
819 private RemoteViews makeTickerView() {
820 if (mTickerView != null) {
821 return mTickerView;
822 } else {
Joe Onorato561d3852010-11-20 18:09:34 -0800823 if (mContentView == null) {
824 return makeRemoteViews(mLargeIcon == null
825 ? R.layout.status_bar_latest_event_ticker
826 : R.layout.status_bar_latest_event_ticker_large_icon);
827 } else {
828 return null;
829 }
Joe Onorato46439ce2010-11-19 13:56:21 -0800830 }
831 }
832
833 public Notification getNotification() {
834 Notification n = new Notification();
835 n.when = mWhen;
836 n.icon = mSmallIcon;
837 n.iconLevel = mSmallIconLevel;
Joe Onorato8595a3d2010-11-19 18:12:07 -0800838 n.number = mNumber;
Joe Onorato46439ce2010-11-19 13:56:21 -0800839 n.contentView = makeContentView();
840 n.contentIntent = mContentIntent;
841 n.deleteIntent = mDeleteIntent;
842 n.fullScreenIntent = mFullScreenIntent;
843 n.tickerText = mTickerText;
844 n.tickerView = makeTickerView();
845 n.largeIcon = mLargeIcon;
846 n.sound = mSound;
847 n.audioStreamType = mAudioStreamType;
848 n.vibrate = mVibrate;
849 n.ledARGB = mLedArgb;
850 n.ledOnMS = mLedOnMs;
851 n.ledOffMS = mLedOffMs;
852 n.defaults = mDefaults;
853 n.flags = mFlags;
854 return n;
855 }
856 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857}