Notification.java revision ebce0115e239919680fc5574ae4ca79e617fcce8
1/* 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 com.android.internal.R; 20 21import android.content.Context; 22import android.content.Intent; 23import android.graphics.Bitmap; 24import android.net.Uri; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.text.TextUtils; 28import android.view.View; 29import android.widget.RemoteViews; 30 31import java.text.NumberFormat; 32 33/** 34 * A class that represents how a persistent notification is to be presented to 35 * the user using the {@link android.app.NotificationManager}. 36 * 37 * <p>The {@link Notification.Builder Notification.Builder} has been added to make it 38 * easier to construct Notifications.</p> 39 * 40 * <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> 43 */ 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 61 * {@link #vibrate}. Using phone vibration requires the 62 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission. 63 * 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 * This is required; notifications with an invalid icon resource will not be shown. 86 */ 87 public int icon; 88 89 /** 90 * If the icon in the status bar is to have more than one level, you can set this. Otherwise, 91 * leave it at its default value of 0. 92 * 93 * @see android.widget.ImageView#setImageLevel 94 * @see android.graphics.drawable#setLevel 95 */ 96 public int iconLevel; 97 98 /** 99 * The number of events that this notification represents. For example, in a new mail 100 * notification, this could be the number of unread messages. This number is superimposed over 101 * the icon in the status bar. If the number is 0 or negative, it is not shown in the status 102 * bar. 103 */ 104 public int number; 105 106 /** 107 * The intent to execute when the expanded status entry is clicked. If 108 * this is an activity, it must include the 109 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires 110 * that you take care of task management as described in the 111 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back 112 * Stack</a> document. 113 */ 114 public PendingIntent contentIntent; 115 116 /** 117 * The intent to execute when the status entry is deleted by the user 118 * with the "Clear All Notifications" button. This probably shouldn't 119 * be launching an activity since several of those will be sent at the 120 * same time. 121 */ 122 public PendingIntent deleteIntent; 123 124 /** 125 * An intent to launch instead of posting the notification to the status bar. 126 * 127 * @see Notification.Builder#setFullScreenIntent 128 */ 129 public PendingIntent fullScreenIntent; 130 131 /** 132 * Text to scroll across the screen when this item is added to 133 * the status bar on large and smaller devices. 134 * 135 * <p>This field is provided separately from the other ticker fields 136 * both for compatibility and to allow an application to choose different 137 * text for when the text scrolls in and when it is displayed all at once 138 * in conjunction with one or more icons. 139 * 140 * @see #tickerView 141 */ 142 public CharSequence tickerText; 143 144 /** 145 * The view to show as the ticker in the status bar when the notification 146 * is posted. 147 */ 148 public RemoteViews tickerView; 149 150 /** 151 * The view that will represent this notification in the expanded status bar. 152 */ 153 public RemoteViews contentView; 154 155 /** 156 * The bitmap that may escape the bounds of the panel and bar. 157 */ 158 public Bitmap largeIcon; 159 160 /** 161 * The sound to play. 162 * 163 * <p> 164 * To play the default notification sound, see {@link #defaults}. 165 * </p> 166 */ 167 public Uri sound; 168 169 /** 170 * Use this constant as the value for audioStreamType to request that 171 * the default stream type for notifications be used. Currently the 172 * default stream type is STREAM_RING. 173 */ 174 public static final int STREAM_DEFAULT = -1; 175 176 /** 177 * The audio stream type to use when playing the sound. 178 * Should be one of the STREAM_ constants from 179 * {@link android.media.AudioManager}. 180 */ 181 public int audioStreamType = STREAM_DEFAULT; 182 183 184 /** 185 * The pattern with which to vibrate. 186 * 187 * <p> 188 * To vibrate the default pattern, see {@link #defaults}. 189 * </p> 190 * 191 * @see android.os.Vibrator#vibrate(long[],int) 192 */ 193 public long[] vibrate; 194 195 /** 196 * The color of the led. The hardware will do its best approximation. 197 * 198 * @see #FLAG_SHOW_LIGHTS 199 * @see #flags 200 */ 201 public int ledARGB; 202 203 /** 204 * The number of milliseconds for the LED to be on while it's flashing. 205 * The hardware will do its best approximation. 206 * 207 * @see #FLAG_SHOW_LIGHTS 208 * @see #flags 209 */ 210 public int ledOnMS; 211 212 /** 213 * The number of milliseconds for the LED to be off while it's flashing. 214 * The hardware will do its best approximation. 215 * 216 * @see #FLAG_SHOW_LIGHTS 217 * @see #flags 218 */ 219 public int ledOffMS; 220 221 /** 222 * Specifies which values should be taken from the defaults. 223 * <p> 224 * To set, OR the desired from {@link #DEFAULT_SOUND}, 225 * {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. For all default 226 * values, use {@link #DEFAULT_ALL}. 227 * </p> 228 */ 229 public int defaults; 230 231 232 /** 233 * Bit to be bitwise-ored into the {@link #flags} field that should be 234 * set if you want the LED on for this notification. 235 * <ul> 236 * <li>To turn the LED off, pass 0 in the alpha channel for colorARGB 237 * or 0 for both ledOnMS and ledOffMS.</li> 238 * <li>To turn the LED on, pass 1 for ledOnMS and 0 for ledOffMS.</li> 239 * <li>To flash the LED, pass the number of milliseconds that it should 240 * be on and off to ledOnMS and ledOffMS.</li> 241 * </ul> 242 * <p> 243 * Since hardware varies, you are not guaranteed that any of the values 244 * you pass are honored exactly. Use the system defaults (TODO) if possible 245 * because they will be set to values that work on any given hardware. 246 * <p> 247 * The alpha channel must be set for forward compatibility. 248 * 249 */ 250 public static final int FLAG_SHOW_LIGHTS = 0x00000001; 251 252 /** 253 * Bit to be bitwise-ored into the {@link #flags} field that should be 254 * set if this notification is in reference to something that is ongoing, 255 * like a phone call. It should not be set if this notification is in 256 * reference to something that happened at a particular point in time, 257 * like a missed phone call. 258 */ 259 public static final int FLAG_ONGOING_EVENT = 0x00000002; 260 261 /** 262 * Bit to be bitwise-ored into the {@link #flags} field that if set, 263 * the audio will be repeated until the notification is 264 * cancelled or the notification window is opened. 265 */ 266 public static final int FLAG_INSISTENT = 0x00000004; 267 268 /** 269 * Bit to be bitwise-ored into the {@link #flags} field that should be 270 * set if you want the sound and/or vibration play each time the 271 * notification is sent, even if it has not been canceled before that. 272 */ 273 public static final int FLAG_ONLY_ALERT_ONCE = 0x00000008; 274 275 /** 276 * Bit to be bitwise-ored into the {@link #flags} field that should be 277 * set if the notification should be canceled when it is clicked by the 278 * user. On tablets, the 279 */ 280 public static final int FLAG_AUTO_CANCEL = 0x00000010; 281 282 /** 283 * Bit to be bitwise-ored into the {@link #flags} field that should be 284 * set if the notification should not be canceled when the user clicks 285 * the Clear all button. 286 */ 287 public static final int FLAG_NO_CLEAR = 0x00000020; 288 289 /** 290 * Bit to be bitwise-ored into the {@link #flags} field that should be 291 * set if this notification represents a currently running service. This 292 * will normally be set for you by {@link Service#startForeground}. 293 */ 294 public static final int FLAG_FOREGROUND_SERVICE = 0x00000040; 295 296 /** 297 * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification 298 * represents a high-priority event that may be shown to the user even if notifications are 299 * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used 300 * in conjunction with {@link #fullScreenIntent}. 301 */ 302 public static final int FLAG_HIGH_PRIORITY = 0x00000080; 303 304 public int flags; 305 306 /** 307 * Constructs a Notification object with everything set to 0. 308 * You might want to consider using {@link Builder} instead. 309 */ 310 public Notification() 311 { 312 this.when = System.currentTimeMillis(); 313 } 314 315 /** 316 * @hide 317 */ 318 public Notification(Context context, int icon, CharSequence tickerText, long when, 319 CharSequence contentTitle, CharSequence contentText, Intent contentIntent) 320 { 321 this.when = when; 322 this.icon = icon; 323 this.tickerText = tickerText; 324 setLatestEventInfo(context, contentTitle, contentText, 325 PendingIntent.getActivity(context, 0, contentIntent, 0)); 326 } 327 328 /** 329 * Constructs a Notification object with the information needed to 330 * have a status bar icon without the standard expanded view. 331 * 332 * @param icon The resource id of the icon to put in the status bar. 333 * @param tickerText The text that flows by in the status bar when the notification first 334 * activates. 335 * @param when The time to show in the time field. In the System.currentTimeMillis 336 * timebase. 337 * 338 * @deprecated Use {@link Builder} instead. 339 */ 340 @Deprecated 341 public Notification(int icon, CharSequence tickerText, long when) 342 { 343 this.icon = icon; 344 this.tickerText = tickerText; 345 this.when = when; 346 } 347 348 /** 349 * Unflatten the notification from a parcel. 350 */ 351 public Notification(Parcel parcel) 352 { 353 int version = parcel.readInt(); 354 355 when = parcel.readLong(); 356 icon = parcel.readInt(); 357 number = parcel.readInt(); 358 if (parcel.readInt() != 0) { 359 contentIntent = PendingIntent.CREATOR.createFromParcel(parcel); 360 } 361 if (parcel.readInt() != 0) { 362 deleteIntent = PendingIntent.CREATOR.createFromParcel(parcel); 363 } 364 if (parcel.readInt() != 0) { 365 tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 366 } 367 if (parcel.readInt() != 0) { 368 tickerView = RemoteViews.CREATOR.createFromParcel(parcel); 369 } 370 if (parcel.readInt() != 0) { 371 contentView = RemoteViews.CREATOR.createFromParcel(parcel); 372 } 373 if (parcel.readInt() != 0) { 374 largeIcon = Bitmap.CREATOR.createFromParcel(parcel); 375 } 376 defaults = parcel.readInt(); 377 flags = parcel.readInt(); 378 if (parcel.readInt() != 0) { 379 sound = Uri.CREATOR.createFromParcel(parcel); 380 } 381 382 audioStreamType = parcel.readInt(); 383 vibrate = parcel.createLongArray(); 384 ledARGB = parcel.readInt(); 385 ledOnMS = parcel.readInt(); 386 ledOffMS = parcel.readInt(); 387 iconLevel = parcel.readInt(); 388 389 if (parcel.readInt() != 0) { 390 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel); 391 } 392 } 393 394 @Override 395 public Notification clone() { 396 Notification that = new Notification(); 397 398 that.when = this.when; 399 that.icon = this.icon; 400 that.number = this.number; 401 402 // PendingIntents are global, so there's no reason (or way) to clone them. 403 that.contentIntent = this.contentIntent; 404 that.deleteIntent = this.deleteIntent; 405 that.fullScreenIntent = this.fullScreenIntent; 406 407 if (this.tickerText != null) { 408 that.tickerText = this.tickerText.toString(); 409 } 410 if (this.tickerView != null) { 411 that.tickerView = this.tickerView.clone(); 412 } 413 if (this.contentView != null) { 414 that.contentView = this.contentView.clone(); 415 } 416 if (this.largeIcon != null) { 417 that.largeIcon = Bitmap.createBitmap(this.largeIcon); 418 } 419 that.iconLevel = this.iconLevel; 420 that.sound = this.sound; // android.net.Uri is immutable 421 that.audioStreamType = this.audioStreamType; 422 423 final long[] vibrate = this.vibrate; 424 if (vibrate != null) { 425 final int N = vibrate.length; 426 final long[] vib = that.vibrate = new long[N]; 427 System.arraycopy(vibrate, 0, vib, 0, N); 428 } 429 430 that.ledARGB = this.ledARGB; 431 that.ledOnMS = this.ledOnMS; 432 that.ledOffMS = this.ledOffMS; 433 that.defaults = this.defaults; 434 435 that.flags = this.flags; 436 437 return that; 438 } 439 440 public int describeContents() { 441 return 0; 442 } 443 444 /** 445 * Flatten this notification from a parcel. 446 */ 447 public void writeToParcel(Parcel parcel, int flags) 448 { 449 parcel.writeInt(1); 450 451 parcel.writeLong(when); 452 parcel.writeInt(icon); 453 parcel.writeInt(number); 454 if (contentIntent != null) { 455 parcel.writeInt(1); 456 contentIntent.writeToParcel(parcel, 0); 457 } else { 458 parcel.writeInt(0); 459 } 460 if (deleteIntent != null) { 461 parcel.writeInt(1); 462 deleteIntent.writeToParcel(parcel, 0); 463 } else { 464 parcel.writeInt(0); 465 } 466 if (tickerText != null) { 467 parcel.writeInt(1); 468 TextUtils.writeToParcel(tickerText, parcel, flags); 469 } else { 470 parcel.writeInt(0); 471 } 472 if (tickerView != null) { 473 parcel.writeInt(1); 474 tickerView.writeToParcel(parcel, 0); 475 } else { 476 parcel.writeInt(0); 477 } 478 if (contentView != null) { 479 parcel.writeInt(1); 480 contentView.writeToParcel(parcel, 0); 481 } else { 482 parcel.writeInt(0); 483 } 484 if (largeIcon != null) { 485 parcel.writeInt(1); 486 largeIcon.writeToParcel(parcel, 0); 487 } else { 488 parcel.writeInt(0); 489 } 490 491 parcel.writeInt(defaults); 492 parcel.writeInt(this.flags); 493 494 if (sound != null) { 495 parcel.writeInt(1); 496 sound.writeToParcel(parcel, 0); 497 } else { 498 parcel.writeInt(0); 499 } 500 parcel.writeInt(audioStreamType); 501 parcel.writeLongArray(vibrate); 502 parcel.writeInt(ledARGB); 503 parcel.writeInt(ledOnMS); 504 parcel.writeInt(ledOffMS); 505 parcel.writeInt(iconLevel); 506 507 if (fullScreenIntent != null) { 508 parcel.writeInt(1); 509 fullScreenIntent.writeToParcel(parcel, 0); 510 } else { 511 parcel.writeInt(0); 512 } 513 } 514 515 /** 516 * Parcelable.Creator that instantiates Notification objects 517 */ 518 public static final Parcelable.Creator<Notification> CREATOR 519 = new Parcelable.Creator<Notification>() 520 { 521 public Notification createFromParcel(Parcel parcel) 522 { 523 return new Notification(parcel); 524 } 525 526 public Notification[] newArray(int size) 527 { 528 return new Notification[size]; 529 } 530 }; 531 532 /** 533 * Sets the {@link #contentView} field to be a view with the standard "Latest Event" 534 * layout. 535 * 536 * <p>Uses the {@link #icon} and {@link #when} fields to set the icon and time fields 537 * in the view.</p> 538 * @param context The context for your application / activity. 539 * @param contentTitle The title that goes in the expanded entry. 540 * @param contentText The text that goes in the expanded entry. 541 * @param contentIntent The intent to launch when the user clicks the expanded notification. 542 * If this is an activity, it must include the 543 * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires 544 * that you take care of task management as described in the 545 * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back 546 * Stack</a> document. 547 * 548 * @deprecated Use {@link Builder} instead. 549 */ 550 @Deprecated 551 public void setLatestEventInfo(Context context, 552 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) { 553 RemoteViews contentView = new RemoteViews(context.getPackageName(), 554 R.layout.status_bar_latest_event_content); 555 if (this.icon != 0) { 556 contentView.setImageViewResource(R.id.icon, this.icon); 557 } 558 if (contentTitle != null) { 559 contentView.setTextViewText(R.id.title, contentTitle); 560 } 561 if (contentText != null) { 562 contentView.setTextViewText(R.id.text, contentText); 563 } 564 if (this.when != 0) { 565 contentView.setLong(R.id.time, "setTime", when); 566 } 567 568 this.contentView = contentView; 569 this.contentIntent = contentIntent; 570 } 571 572 @Override 573 public String toString() { 574 StringBuilder sb = new StringBuilder(); 575 sb.append("Notification(contentView="); 576 if (contentView != null) { 577 sb.append(contentView.getPackage()); 578 sb.append("/0x"); 579 sb.append(Integer.toHexString(contentView.getLayoutId())); 580 } else { 581 sb.append("null"); 582 } 583 sb.append(" vibrate="); 584 if (this.vibrate != null) { 585 int N = this.vibrate.length-1; 586 sb.append("["); 587 for (int i=0; i<N; i++) { 588 sb.append(this.vibrate[i]); 589 sb.append(','); 590 } 591 if (N != -1) { 592 sb.append(this.vibrate[N]); 593 } 594 sb.append("]"); 595 } else if ((this.defaults & DEFAULT_VIBRATE) != 0) { 596 sb.append("default"); 597 } else { 598 sb.append("null"); 599 } 600 sb.append(",sound="); 601 if (this.sound != null) { 602 sb.append(this.sound.toString()); 603 } else if ((this.defaults & DEFAULT_SOUND) != 0) { 604 sb.append("default"); 605 } else { 606 sb.append("null"); 607 } 608 sb.append(",defaults=0x"); 609 sb.append(Integer.toHexString(this.defaults)); 610 sb.append(",flags=0x"); 611 sb.append(Integer.toHexString(this.flags)); 612 if ((this.flags & FLAG_HIGH_PRIORITY) != 0) { 613 sb.append("!!!1!one!"); 614 } 615 sb.append(")"); 616 return sb.toString(); 617 } 618 619 /** 620 * Builder class for {@link Notification} objects. Allows easier control over 621 * all the flags, as well as help constructing the typical notification layouts. 622 */ 623 public static class Builder { 624 private Context mContext; 625 626 private long mWhen; 627 private int mSmallIcon; 628 private int mSmallIconLevel; 629 private int mNumber; 630 private CharSequence mContentTitle; 631 private CharSequence mContentText; 632 private CharSequence mContentInfo; 633 private PendingIntent mContentIntent; 634 private RemoteViews mContentView; 635 private PendingIntent mDeleteIntent; 636 private PendingIntent mFullScreenIntent; 637 private CharSequence mTickerText; 638 private RemoteViews mTickerView; 639 private Bitmap mLargeIcon; 640 private Uri mSound; 641 private int mAudioStreamType; 642 private long[] mVibrate; 643 private int mLedArgb; 644 private int mLedOnMs; 645 private int mLedOffMs; 646 private int mDefaults; 647 private int mFlags; 648 649 /** 650 * Constructor. 651 * 652 * Automatically sets the when field to {@link System#currentTimeMillis() 653 * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}. 654 * 655 * @param context A {@link Context} that will be used to construct the 656 * RemoteViews. The Context will not be held past the lifetime of this 657 * Builder object. 658 */ 659 public Builder(Context context) { 660 mContext = context; 661 662 // Set defaults to match the defaults of a Notification 663 mWhen = System.currentTimeMillis(); 664 mAudioStreamType = STREAM_DEFAULT; 665 } 666 667 /** 668 * Set the time that the event occurred. Notifications in the panel are 669 * sorted by this time. 670 */ 671 public Builder setWhen(long when) { 672 mWhen = when; 673 return this; 674 } 675 676 /** 677 * Set the small icon to use in the notification layouts. Different classes of devices 678 * may return different sizes. See the UX guidelines for more information on how to 679 * design these icons. 680 * 681 * @param icon A resource ID in the application's package of the drawble to use. 682 */ 683 public Builder setSmallIcon(int icon) { 684 mSmallIcon = icon; 685 return this; 686 } 687 688 /** 689 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 690 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 691 * LevelListDrawable}. 692 * 693 * @param icon A resource ID in the application's package of the drawble to use. 694 * @param level The level to use for the icon. 695 * 696 * @see android.graphics.drawable.LevelListDrawable 697 */ 698 public Builder setSmallIcon(int icon, int level) { 699 mSmallIcon = icon; 700 mSmallIconLevel = level; 701 return this; 702 } 703 704 /** 705 * Set the title (first row) of the notification, in a standard notification. 706 */ 707 public Builder setContentTitle(CharSequence title) { 708 mContentTitle = title; 709 return this; 710 } 711 712 /** 713 * Set the text (second row) of the notification, in a standard notification. 714 */ 715 public Builder setContentText(CharSequence text) { 716 mContentText = text; 717 return this; 718 } 719 720 /** 721 * Set the large number at the right-hand side of the notification. This is 722 * equivalent to setContentInfo, although it might show the number in a different 723 * font size for readability. 724 */ 725 public Builder setNumber(int number) { 726 mNumber = number; 727 return this; 728 } 729 730 /** 731 * Set the large text at the right-hand side of the notification. 732 */ 733 public Builder setContentInfo(CharSequence info) { 734 mContentInfo = info; 735 return this; 736 } 737 738 /** 739 * Supply a custom RemoteViews to use instead of the standard one. 740 */ 741 public Builder setContent(RemoteViews views) { 742 mContentView = views; 743 return this; 744 } 745 746 /** 747 * Supply a {@link PendingIntent} to send when the notification is clicked. 748 * If you do not supply an intent, you can now add PendingIntents to individual 749 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 750 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. 751 */ 752 public Builder setContentIntent(PendingIntent intent) { 753 mContentIntent = intent; 754 return this; 755 } 756 757 /** 758 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 759 * directly from the notification panel. For example, this intent is sent when the user 760 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 761 * intent is not sent when the application calls {@link NotificationManager#cancel 762 * NotificationManager.cancel(int)}. 763 */ 764 public Builder setDeleteIntent(PendingIntent intent) { 765 mDeleteIntent = intent; 766 return this; 767 } 768 769 /** 770 * An intent to launch instead of posting the notification to the status bar. 771 * Only for use with extremely high-priority notifications demanding the user's 772 * <strong>immediate</strong> attention, such as an incoming phone call or 773 * alarm clock that the user has explicitly set to a particular time. 774 * If this facility is used for something else, please give the user an option 775 * to turn it off and use a normal notification, as this can be extremely 776 * disruptive. 777 * 778 * @param intent The pending intent to launch. 779 * @param highPriority Passing true will cause this notification to be sent 780 * even if other notifications are suppressed. 781 */ 782 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 783 mFullScreenIntent = intent; 784 setFlag(FLAG_HIGH_PRIORITY, highPriority); 785 return this; 786 } 787 788 /** 789 * Set the text that is displayed in the status bar when the notification first 790 * arrives. 791 */ 792 public Builder setTicker(CharSequence tickerText) { 793 mTickerText = tickerText; 794 return this; 795 } 796 797 /** 798 * Set the text that is displayed in the status bar when the notification first 799 * arrives, and also a RemoteViews object that may be displayed instead on some 800 * devices. 801 */ 802 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 803 mTickerText = tickerText; 804 mTickerView = views; 805 return this; 806 } 807 808 /** 809 * Set the large icon that is shown in the ticker and notification. 810 */ 811 public Builder setLargeIcon(Bitmap icon) { 812 mLargeIcon = icon; 813 return this; 814 } 815 816 /** 817 * Set the sound to play. It will play on the default stream. 818 */ 819 public Builder setSound(Uri sound) { 820 mSound = sound; 821 mAudioStreamType = STREAM_DEFAULT; 822 return this; 823 } 824 825 /** 826 * Set the sound to play. It will play on the stream you supply. 827 * 828 * @see #STREAM_DEFAULT 829 * @see AudioManager for the <code>STREAM_</code> constants. 830 */ 831 public Builder setSound(Uri sound, int streamType) { 832 mSound = sound; 833 mAudioStreamType = streamType; 834 return this; 835 } 836 837 /** 838 * Set the vibration pattern to use. 839 * 840 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 841 * parameter. 842 */ 843 public Builder setVibrate(long[] pattern) { 844 mVibrate = pattern; 845 return this; 846 } 847 848 /** 849 * Set the argb value that you would like the LED on the device to blnk, as well as the 850 * rate. The rate is specified in terms of the number of milliseconds to be on 851 * and then the number of milliseconds to be off. 852 */ 853 public Builder setLights(int argb, int onMs, int offMs) { 854 mLedArgb = argb; 855 mLedOnMs = onMs; 856 mLedOffMs = offMs; 857 return this; 858 } 859 860 /** 861 * Set whether this is an ongoing notification. 862 * 863 * <p>Ongoing notifications differ from regular notifications in the following ways: 864 * <ul> 865 * <li>Ongoing notifications are sorted above the regular notifications in the 866 * notification panel.</li> 867 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 868 * by the "Clear all" button. 869 * </ul> 870 */ 871 public Builder setOngoing(boolean ongoing) { 872 setFlag(FLAG_ONGOING_EVENT, ongoing); 873 return this; 874 } 875 876 /** 877 * Set this flag if you would only like the sound, vibrate 878 * and ticker to be played if the notification is not already showing. 879 */ 880 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 881 setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 882 return this; 883 } 884 885 /** 886 * Setting this flag will make it so the notification is automatically 887 * canceled when the user clicks it in the panel. The PendingIntent 888 * set with {@link #setDeleteIntent} will be broadcast when the notification 889 * is canceled. 890 */ 891 public Builder setAutoCancel(boolean autoCancel) { 892 setFlag(FLAG_AUTO_CANCEL, autoCancel); 893 return this; 894 } 895 896 /** 897 * Set the default notification options that will be used. 898 * <p> 899 * The value should be one or more of the following fields combined with 900 * bitwise-or: 901 * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}. 902 * <p> 903 * For all default values, use {@link #DEFAULT_ALL}. 904 */ 905 public Builder setDefaults(int defaults) { 906 mDefaults = defaults; 907 return this; 908 } 909 910 private void setFlag(int mask, boolean value) { 911 if (value) { 912 mFlags |= mask; 913 } else { 914 mFlags &= ~mask; 915 } 916 } 917 918 private RemoteViews makeRemoteViews(int resId) { 919 RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId); 920 if (mSmallIcon != 0) { 921 contentView.setImageViewResource(R.id.icon, mSmallIcon); 922 } 923 if (mContentTitle != null) { 924 contentView.setTextViewText(R.id.title, mContentTitle); 925 } 926 if (mContentText != null) { 927 contentView.setTextViewText(R.id.text, mContentText); 928 } 929 if (mContentInfo != null) { 930 contentView.setTextViewText(R.id.info, mContentInfo); 931 } else if (mNumber > 0) { 932 final int tooBig = mContext.getResources().getInteger( 933 R.integer.status_bar_notification_info_maxnum); 934 if (mNumber > tooBig) { 935 contentView.setTextViewText(R.id.info, mContext.getResources().getString( 936 R.string.status_bar_notification_info_overflow)); 937 } else { 938 NumberFormat f = NumberFormat.getIntegerInstance(); 939 contentView.setTextViewText(R.id.info, f.format(mNumber)); 940 } 941 } else { 942 contentView.setViewVisibility(R.id.info, View.GONE); 943 } 944 if (mWhen != 0) { 945 contentView.setLong(R.id.time, "setTime", mWhen); 946 } 947 return contentView; 948 } 949 950 private RemoteViews makeContentView() { 951 if (mContentView != null) { 952 return mContentView; 953 } else { 954 return makeRemoteViews(mLargeIcon == null 955 ? R.layout.status_bar_latest_event_content 956 : R.layout.status_bar_latest_event_content_large_icon); 957 } 958 } 959 960 private RemoteViews makeTickerView() { 961 if (mTickerView != null) { 962 return mTickerView; 963 } else { 964 if (mContentView == null) { 965 return makeRemoteViews(mLargeIcon == null 966 ? R.layout.status_bar_latest_event_ticker 967 : R.layout.status_bar_latest_event_ticker_large_icon); 968 } else { 969 return null; 970 } 971 } 972 } 973 974 /** 975 * Combine all of the options that have been set and return a new {@link Notification} 976 * object. 977 */ 978 public Notification getNotification() { 979 Notification n = new Notification(); 980 n.when = mWhen; 981 n.icon = mSmallIcon; 982 n.iconLevel = mSmallIconLevel; 983 n.number = mNumber; 984 n.contentView = makeContentView(); 985 n.contentIntent = mContentIntent; 986 n.deleteIntent = mDeleteIntent; 987 n.fullScreenIntent = mFullScreenIntent; 988 n.tickerText = mTickerText; 989 n.tickerView = makeTickerView(); 990 n.largeIcon = mLargeIcon; 991 n.sound = mSound; 992 n.audioStreamType = mAudioStreamType; 993 n.vibrate = mVibrate; 994 n.ledARGB = mLedArgb; 995 n.ledOnMS = mLedOnMs; 996 n.ledOffMS = mLedOffMs; 997 n.defaults = mDefaults; 998 n.flags = mFlags; 999 if (mLedOnMs != 0 && mLedOffMs != 0) { 1000 n.flags |= FLAG_SHOW_LIGHTS; 1001 } 1002 if ((mDefaults & DEFAULT_LIGHTS) != 0) { 1003 n.flags |= FLAG_SHOW_LIGHTS; 1004 } 1005 return n; 1006 } 1007 } 1008} 1009