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