blob: e602518d3106c8e8e9a184bb364cc4e9e0c9045d [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;
Joe Onoratoef1e7762010-09-17 18:38:38 -040024import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.media.AudioManager;
26import android.net.Uri;
27import android.os.Parcel;
28import android.os.Parcelable;
29import android.text.TextUtils;
30import android.text.format.DateFormat;
31import android.text.format.DateUtils;
32import android.widget.RemoteViews;
33
34/**
35 * A class that represents how a persistent notification is to be presented to
36 * the user using the {@link android.app.NotificationManager}.
37 *
Scott Mainb8b36452009-04-26 15:50:49 -070038 * <p>For a guide to creating notifications, see the
39 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
40 * Bar Notifications</a> document in the Dev Guide.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041 */
42public class Notification implements Parcelable
43{
44 /**
45 * Use all default values (where applicable).
46 */
47 public static final int DEFAULT_ALL = ~0;
48
49 /**
50 * Use the default notification sound. This will ignore any given
51 * {@link #sound}.
52 *
53 * @see #defaults
54 */
55 public static final int DEFAULT_SOUND = 1;
56
57 /**
58 * Use the default notification vibrate. This will ignore any given
Scott Mainb8b36452009-04-26 15:50:49 -070059 * {@link #vibrate}. Using phone vibration requires the
60 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 *
62 * @see #defaults
63 */
64 public static final int DEFAULT_VIBRATE = 2;
65
66 /**
67 * Use the default notification lights. This will ignore the
68 * {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
69 * {@link #ledOnMS}.
70 *
71 * @see #defaults
72 */
73 public static final int DEFAULT_LIGHTS = 4;
74
75 /**
76 * The timestamp for the notification. The icons and expanded views
77 * are sorted by this key.
78 */
79 public long when;
80
81 /**
82 * The resource id of a drawable to use as the icon in the status bar.
83 */
84 public int icon;
85
86 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -040087 * The number of events that this notification represents. For example, in a new mail
88 * notification, this could be the number of unread messages. This number is superimposed over
89 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
90 * bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 */
92 public int number;
93
94 /**
95 * The intent to execute when the expanded status entry is clicked. If
96 * this is an activity, it must include the
97 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
98 * that you take care of task management as described in the <em>Activities and Tasks</em>
99 * section of the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application
100 * Fundamentals</a> document.
101 */
102 public PendingIntent contentIntent;
103
104 /**
105 * The intent to execute when the status entry is deleted by the user
106 * with the "Clear All Notifications" button. This probably shouldn't
107 * be launching an activity since several of those will be sent at the
108 * same time.
109 */
110 public PendingIntent deleteIntent;
111
112 /**
Dianne Hackborn170bae72010-09-03 15:14:28 -0700113 * An intent to launch instead of posting the notification to the status bar.
114 * Only for use with extremely high-priority notifications demanding the user's
Dianne Hackborn392fea52010-09-09 16:44:01 -0700115 * <strong>immediate</strong> attention, such as an incoming phone call or
Dianne Hackborn170bae72010-09-03 15:14:28 -0700116 * alarm clock that the user has explicitly set to a particular time.
Dianne Hackborn170bae72010-09-03 15:14:28 -0700117 * If this facility is used for something else, please give the user an option
118 * to turn it off and use a normal notification, as this can be extremely
119 * disruptive.
Dianne Hackborn61714012010-09-03 16:40:58 -0700120 *
121 * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
122 * will reach the user even when other notifications are suppressed.
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400123 */
124 public PendingIntent fullScreenIntent;
125
126 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 * Text to scroll across the screen when this item is added to
Joe Onoratoef1e7762010-09-17 18:38:38 -0400128 * the status bar on large and smaller devices.
129 *
130 * <p>This field is provided separately from the other ticker fields
131 * both for compatibility and to allow an application to choose different
132 * text for when the text scrolls in and when it is displayed all at once
133 * in conjunction with one or more icons.
134 *
135 * @see #tickerTitle
136 * @see #tickerSubtitle
137 * @see #tickerIcons
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 */
139 public CharSequence tickerText;
140
141 /**
Joe Onoratoef1e7762010-09-17 18:38:38 -0400142 * The title line for the ticker over a the fat status bar on xlarge devices.
143 *
144 * @see #tickerText
145 * @see #tickerSubtitle
146 * @see #tickerIcons
147 */
148 public CharSequence tickerTitle;
149
150 /**
151 * The subtitle line for the ticker over a the fat status bar on xlarge devices.
152 *
153 * @see #tickerText
154 * @see #tickerTitle
155 * @see #tickerIcons
156 */
157 public CharSequence tickerSubtitle;
158
159 /**
160 * The icons to show to the left of the other ticker fields.
161 *
162 * @see #tickerText
163 * @see #tickerTitle
164 * @see #tickerSubtitle
165 */
166 public Bitmap[] tickerIcons;
167
168 /**
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400169 * The view that will represent this notification in the expanded status bar.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 */
171 public RemoteViews contentView;
172
173 /**
174 * If the icon in the status bar is to have more than one level, you can set this. Otherwise,
175 * leave it at its default value of 0.
176 *
177 * @see android.widget.ImageView#setImageLevel
178 * @see android.graphics.drawable#setLevel
179 */
180 public int iconLevel;
181
182 /**
183 * The sound to play.
184 *
185 * <p>
186 * To play the default notification sound, see {@link #defaults}.
187 * </p>
188 */
189 public Uri sound;
190
191 /**
192 * Use this constant as the value for audioStreamType to request that
193 * the default stream type for notifications be used. Currently the
194 * default stream type is STREAM_RING.
195 */
196 public static final int STREAM_DEFAULT = -1;
197
198 /**
199 * The audio stream type to use when playing the sound.
200 * Should be one of the STREAM_ constants from
201 * {@link android.media.AudioManager}.
202 */
203 public int audioStreamType = STREAM_DEFAULT;
204
205
206 /**
Scott Mainb8b36452009-04-26 15:50:49 -0700207 * The pattern with which to vibrate.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 *
209 * <p>
210 * To vibrate the default pattern, see {@link #defaults}.
211 * </p>
212 *
213 * @see android.os.Vibrator#vibrate(long[],int)
214 */
215 public long[] vibrate;
216
217 /**
218 * The color of the led. The hardware will do its best approximation.
219 *
220 * @see #FLAG_SHOW_LIGHTS
221 * @see #flags
222 */
223 public int ledARGB;
224
225 /**
226 * The number of milliseconds for the LED to be on while it's flashing.
227 * The hardware will do its best approximation.
228 *
229 * @see #FLAG_SHOW_LIGHTS
230 * @see #flags
231 */
232 public int ledOnMS;
233
234 /**
235 * The number of milliseconds for the LED to be off while it's flashing.
236 * The hardware will do its best approximation.
237 *
238 * @see #FLAG_SHOW_LIGHTS
239 * @see #flags
240 */
241 public int ledOffMS;
242
243 /**
244 * Specifies which values should be taken from the defaults.
245 * <p>
246 * To set, OR the desired from {@link #DEFAULT_SOUND},
247 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default
248 * values, use {@link #DEFAULT_ALL}.
249 * </p>
250 */
251 public int defaults;
252
253
254 /**
255 * Bit to be bitwise-ored into the {@link #flags} field that should be
256 * set if you want the LED on for this notification.
257 * <ul>
258 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB
259 * or 0 for both ledOnMS and ledOffMS.</li>
260 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li>
261 * <li>To flash the LED, pass the number of milliseconds that it should
262 * be on and off to ledOnMS and ledOffMS.</li>
263 * </ul>
264 * <p>
265 * Since hardware varies, you are not guaranteed that any of the values
266 * you pass are honored exactly. Use the system defaults (TODO) if possible
267 * because they will be set to values that work on any given hardware.
268 * <p>
269 * The alpha channel must be set for forward compatibility.
270 *
271 */
272 public static final int FLAG_SHOW_LIGHTS = 0x00000001;
273
274 /**
275 * Bit to be bitwise-ored into the {@link #flags} field that should be
276 * set if this notification is in reference to something that is ongoing,
277 * like a phone call. It should not be set if this notification is in
278 * reference to something that happened at a particular point in time,
279 * like a missed phone call.
280 */
281 public static final int FLAG_ONGOING_EVENT = 0x00000002;
282
283 /**
284 * Bit to be bitwise-ored into the {@link #flags} field that if set,
Scott Mainb8b36452009-04-26 15:50:49 -0700285 * the audio will be repeated until the notification is
286 * cancelled or the notification window is opened.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 */
288 public static final int FLAG_INSISTENT = 0x00000004;
289
290 /**
291 * Bit to be bitwise-ored into the {@link #flags} field that should be
292 * set if you want the sound and/or vibration play each time the
293 * notification is sent, even if it has not been canceled before that.
294 */
295 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008;
296
297 /**
298 * Bit to be bitwise-ored into the {@link #flags} field that should be
299 * set if the notification should be canceled when it is clicked by the
300 * user.
301 */
302 public static final int FLAG_AUTO_CANCEL = 0x00000010;
303
304 /**
305 * Bit to be bitwise-ored into the {@link #flags} field that should be
306 * set if the notification should not be canceled when the user clicks
307 * the Clear all button.
308 */
309 public static final int FLAG_NO_CLEAR = 0x00000020;
310
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700311 /**
312 * Bit to be bitwise-ored into the {@link #flags} field that should be
313 * set if this notification represents a currently running service. This
314 * will normally be set for you by {@link Service#startForeground}.
315 */
316 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
317
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400318 /**
319 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
320 * represents a high-priority event that may be shown to the user even if notifications are
321 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
322 * in conjunction with {@link #fullScreenIntent}.
323 */
324 public static final int FLAG_HIGH_PRIORITY = 0x00000080;
325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 public int flags;
327
328 /**
329 * Constructs a Notification object with everything set to 0.
330 */
331 public Notification()
332 {
333 this.when = System.currentTimeMillis();
334 }
335
336 /**
337 * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
338 * @hide
339 */
340 public Notification(Context context, int icon, CharSequence tickerText, long when,
341 CharSequence contentTitle, CharSequence contentText, Intent contentIntent)
342 {
343 this.when = when;
344 this.icon = icon;
345 this.tickerText = tickerText;
346 setLatestEventInfo(context, contentTitle, contentText,
347 PendingIntent.getActivity(context, 0, contentIntent, 0));
348 }
349
350 /**
351 * Constructs a Notification object with the information needed to
352 * have a status bar icon without the standard expanded view.
353 *
354 * @param icon The resource id of the icon to put in the status bar.
355 * @param tickerText The text that flows by in the status bar when the notification first
356 * activates.
357 * @param when The time to show in the time field. In the System.currentTimeMillis
358 * timebase.
359 */
360 public Notification(int icon, CharSequence tickerText, long when)
361 {
362 this.icon = icon;
363 this.tickerText = tickerText;
364 this.when = when;
365 }
366
367 /**
368 * Unflatten the notification from a parcel.
369 */
370 public Notification(Parcel parcel)
371 {
372 int version = parcel.readInt();
373
374 when = parcel.readLong();
375 icon = parcel.readInt();
376 number = parcel.readInt();
377 if (parcel.readInt() != 0) {
378 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
379 }
380 if (parcel.readInt() != 0) {
381 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel);
382 }
383 if (parcel.readInt() != 0) {
384 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
385 }
386 if (parcel.readInt() != 0) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400387 tickerTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
388 }
389 if (parcel.readInt() != 0) {
390 tickerSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
391 }
392 final int tickerIconCount = parcel.readInt();
393 if (tickerIconCount >= 0) {
394 tickerIcons = new Bitmap[tickerIconCount];
395 for (int i=0; i<tickerIconCount; i++) {
396 if (parcel.readInt() != 0) {
397 tickerIcons[i] = Bitmap.CREATOR.createFromParcel(parcel);
398 }
399 }
400 }
401 if (parcel.readInt() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 contentView = RemoteViews.CREATOR.createFromParcel(parcel);
403 }
404 defaults = parcel.readInt();
405 flags = parcel.readInt();
406 if (parcel.readInt() != 0) {
407 sound = Uri.CREATOR.createFromParcel(parcel);
408 }
409
410 audioStreamType = parcel.readInt();
411 vibrate = parcel.createLongArray();
412 ledARGB = parcel.readInt();
413 ledOnMS = parcel.readInt();
414 ledOffMS = parcel.readInt();
415 iconLevel = parcel.readInt();
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400416
417 if (parcel.readInt() != 0) {
418 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
421
Joe Onorato18e69df2010-05-17 22:26:12 -0700422 public Notification clone() {
423 Notification that = new Notification();
424
425 that.when = this.when;
426 that.icon = this.icon;
427 that.number = this.number;
428
429 // PendingIntents are global, so there's no reason (or way) to clone them.
430 that.contentIntent = this.contentIntent;
431 that.deleteIntent = this.deleteIntent;
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400432 that.fullScreenIntent = this.fullScreenIntent;
Joe Onorato18e69df2010-05-17 22:26:12 -0700433
434 if (this.tickerText != null) {
435 that.tickerText = this.tickerText.toString();
436 }
Joe Onoratoef1e7762010-09-17 18:38:38 -0400437 if (this.tickerTitle != null) {
438 that.tickerTitle = this.tickerTitle.toString();
439 }
440 if (this.tickerSubtitle != null) {
441 that.tickerSubtitle = this.tickerSubtitle.toString();
442 }
443 if (this.tickerIcons != null) {
444 final int N = this.tickerIcons.length;
445 that.tickerIcons = new Bitmap[N];
446 for (int i=0; i<N; i++) {
447 that.tickerIcons[i] = Bitmap.createBitmap(this.tickerIcons[i]);
448 }
449 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700450 if (this.contentView != null) {
451 that.contentView = this.contentView.clone();
452 }
453 that.iconLevel = that.iconLevel;
454 that.sound = this.sound; // android.net.Uri is immutable
455 that.audioStreamType = this.audioStreamType;
456
457 final long[] vibrate = this.vibrate;
458 if (vibrate != null) {
459 final int N = vibrate.length;
460 final long[] vib = that.vibrate = new long[N];
461 System.arraycopy(vibrate, 0, vib, 0, N);
462 }
463
464 that.ledARGB = this.ledARGB;
465 that.ledOnMS = this.ledOnMS;
466 that.ledOffMS = this.ledOffMS;
467 that.defaults = this.defaults;
468
469 that.flags = this.flags;
470
471 return that;
472 }
473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 public int describeContents() {
475 return 0;
476 }
477
478 /**
479 * Flatten this notification from a parcel.
480 */
481 public void writeToParcel(Parcel parcel, int flags)
482 {
483 parcel.writeInt(1);
484
485 parcel.writeLong(when);
486 parcel.writeInt(icon);
487 parcel.writeInt(number);
488 if (contentIntent != null) {
489 parcel.writeInt(1);
490 contentIntent.writeToParcel(parcel, 0);
491 } else {
492 parcel.writeInt(0);
493 }
494 if (deleteIntent != null) {
495 parcel.writeInt(1);
496 deleteIntent.writeToParcel(parcel, 0);
497 } else {
498 parcel.writeInt(0);
499 }
500 if (tickerText != null) {
501 parcel.writeInt(1);
502 TextUtils.writeToParcel(tickerText, parcel, flags);
503 } else {
504 parcel.writeInt(0);
505 }
Joe Onoratoef1e7762010-09-17 18:38:38 -0400506 if (tickerTitle != null) {
507 parcel.writeInt(1);
508 TextUtils.writeToParcel(tickerTitle, parcel, flags);
509 } else {
510 parcel.writeInt(0);
511 }
512 if (tickerSubtitle != null) {
513 parcel.writeInt(1);
514 TextUtils.writeToParcel(tickerSubtitle, parcel, flags);
515 } else {
516 parcel.writeInt(0);
517 }
518 if (tickerIcons != null) {
519 final int N = tickerIcons.length;
520 parcel.writeInt(N);
521 for (int i=0; i<N; i++) {
522 if (tickerIcons[i] != null) {
523 parcel.writeInt(1);
524 tickerIcons[i].writeToParcel(parcel, flags);
525 } else {
526 parcel.writeInt(0);
527 }
528 }
529 } else {
530 parcel.writeInt(-1);
531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 if (contentView != null) {
533 parcel.writeInt(1);
534 contentView.writeToParcel(parcel, 0);
535 } else {
536 parcel.writeInt(0);
537 }
538
539 parcel.writeInt(defaults);
540 parcel.writeInt(this.flags);
541
542 if (sound != null) {
543 parcel.writeInt(1);
544 sound.writeToParcel(parcel, 0);
545 } else {
546 parcel.writeInt(0);
547 }
548 parcel.writeInt(audioStreamType);
549 parcel.writeLongArray(vibrate);
550 parcel.writeInt(ledARGB);
551 parcel.writeInt(ledOnMS);
552 parcel.writeInt(ledOffMS);
553 parcel.writeInt(iconLevel);
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400554
555 if (fullScreenIntent != null) {
556 parcel.writeInt(1);
557 fullScreenIntent.writeToParcel(parcel, 0);
558 } else {
559 parcel.writeInt(0);
560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 }
562
563 /**
564 * Parcelable.Creator that instantiates Notification objects
565 */
566 public static final Parcelable.Creator<Notification> CREATOR
567 = new Parcelable.Creator<Notification>()
568 {
569 public Notification createFromParcel(Parcel parcel)
570 {
571 return new Notification(parcel);
572 }
573
574 public Notification[] newArray(int size)
575 {
576 return new Notification[size];
577 }
578 };
579
580 /**
581 * Sets the {@link #contentView} field to be a view with the standard "Latest Event"
582 * layout.
583 *
584 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields
585 * in the view.</p>
586 * @param context The context for your application / activity.
587 * @param contentTitle The title that goes in the expanded entry.
588 * @param contentText The text that goes in the expanded entry.
589 * @param contentIntent The intent to launch when the user clicks the expanded notification.
590 * If this is an activity, it must include the
591 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
592 * that you take care of task management as described in
593 * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
594 */
595 public void setLatestEventInfo(Context context,
596 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
597 RemoteViews contentView = new RemoteViews(context.getPackageName(),
598 com.android.internal.R.layout.status_bar_latest_event_content);
599 if (this.icon != 0) {
600 contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
601 }
602 if (contentTitle != null) {
603 contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
604 }
605 if (contentText != null) {
606 contentView.setTextViewText(com.android.internal.R.id.text, contentText);
607 }
608 if (this.when != 0) {
Joe Onoratoc83bb732010-01-19 16:32:22 -0800609 contentView.setLong(com.android.internal.R.id.time, "setTime", when);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 }
611
612 this.contentView = contentView;
613 this.contentIntent = contentIntent;
614 }
615
616 @Override
617 public String toString() {
618 StringBuilder sb = new StringBuilder();
619 sb.append("Notification(vibrate=");
620 if (this.vibrate != null) {
621 int N = this.vibrate.length-1;
622 sb.append("[");
623 for (int i=0; i<N; i++) {
624 sb.append(this.vibrate[i]);
625 sb.append(',');
626 }
Simon Schoar8cf97d92009-06-10 22:08:37 +0200627 if (N != -1) {
628 sb.append(this.vibrate[N]);
629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 sb.append("]");
631 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) {
632 sb.append("default");
633 } else {
634 sb.append("null");
635 }
636 sb.append(",sound=");
637 if (this.sound != null) {
638 sb.append(this.sound.toString());
639 } else if ((this.defaults & DEFAULT_SOUND) != 0) {
640 sb.append("default");
641 } else {
642 sb.append("null");
643 }
644 sb.append(",defaults=0x");
645 sb.append(Integer.toHexString(this.defaults));
Daniel Sandlere46cbd32010-06-17 10:35:26 -0400646 sb.append(",flags=0x");
647 sb.append(Integer.toHexString(this.flags));
648 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
649 sb.append("!!!1!one!");
650 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 sb.append(")");
652 return sb.toString();
653 }
654}