Notification.java revision 52f80cd36f406725e85a1825741a45c69de3d898
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 java.text.NumberFormat; 20import java.util.Date; 21 22import android.app.PendingIntent; 23import android.content.Context; 24import android.content.Intent; 25import android.graphics.Bitmap; 26import 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; 33import android.util.Slog; 34import android.view.View; 35import android.widget.RemoteViews; 36 37import com.android.internal.R; 38 39/** 40 * A class that represents how a persistent notification is to be presented to 41 * the user using the {@link android.app.NotificationManager}. 42 * 43 * <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> 46 */ 47public class Notification implements Parcelable 48{ 49 private static final String TAG = "Notification"; 50 51 /** 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 66 * {@link #vibrate}. Using phone vibration requires the 67 * {@link android.Manifest.permission#VIBRATE VIBRATE} permission. 68 * 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 /** 94 * 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 /** 103 * 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. 107 */ 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 /** 129 * 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 131 * <strong>immediate</strong> attention, such as an incoming phone call or 132 * alarm clock that the user has explicitly set to a particular time. 133 * 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. 136 * 137 * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification 138 * will reach the user even when other notifications are suppressed. 139 */ 140 public PendingIntent fullScreenIntent; 141 142 /** 143 * Text to scroll across the screen when this item is added to 144 * 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 * 151 * @see #tickerView 152 */ 153 public CharSequence tickerText; 154 155 /** 156 * The view to show as the ticker in the status bar when the notification 157 * is posted. 158 */ 159 public RemoteViews tickerView; 160 161 /** 162 * The view that will represent this notification in the expanded status bar. 163 */ 164 public RemoteViews contentView; 165 166 /** 167 * The bitmap that may escape the bounds of the panel and bar. 168 */ 169 public Bitmap largeIcon; 170 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 /** 196 * The pattern with which to vibrate. 197 * 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, 274 * the audio will be repeated until the notification is 275 * cancelled or the notification window is opened. 276 */ 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 300 /** 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 307 /** 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 315 public int flags; 316 317 /** 318 * Constructs a Notification object with everything set to 0. 319 * You might want to consider using {@link Builder} instead. 320 */ 321 public Notification() 322 { 323 this.when = System.currentTimeMillis(); 324 } 325 326 /** 327 * @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. 348 * 349 * @deprecated Use {@link Builder} instead. 350 */ 351 @Deprecated 352 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) { 379 tickerView = RemoteViews.CREATOR.createFromParcel(parcel); 380 } 381 if (parcel.readInt() != 0) { 382 contentView = RemoteViews.CREATOR.createFromParcel(parcel); 383 } 384 if (parcel.readInt() != 0) { 385 largeIcon = Bitmap.CREATOR.createFromParcel(parcel); 386 } 387 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(); 399 400 if (parcel.readInt() != 0) { 401 fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel); 402 } 403 } 404 405 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; 415 that.fullScreenIntent = this.fullScreenIntent; 416 417 if (this.tickerText != null) { 418 that.tickerText = this.tickerText.toString(); 419 } 420 if (this.tickerView != null) { 421 that.tickerView = this.tickerView.clone(); 422 } 423 if (this.contentView != null) { 424 that.contentView = this.contentView.clone(); 425 } 426 if (this.largeIcon != null) { 427 that.largeIcon = Bitmap.createBitmap(this.largeIcon); 428 } 429 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 450 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 } 482 if (tickerView != null) { 483 parcel.writeInt(1); 484 tickerView.writeToParcel(parcel, 0); 485 } else { 486 parcel.writeInt(0); 487 } 488 if (contentView != null) { 489 parcel.writeInt(1); 490 contentView.writeToParcel(parcel, 0); 491 } else { 492 parcel.writeInt(0); 493 } 494 if (largeIcon != null) { 495 parcel.writeInt(1); 496 largeIcon.writeToParcel(parcel, 0); 497 } else { 498 parcel.writeInt(0); 499 } 500 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); 516 517 if (fullScreenIntent != null) { 518 parcel.writeInt(1); 519 fullScreenIntent.writeToParcel(parcel, 0); 520 } else { 521 parcel.writeInt(0); 522 } 523 } 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>. 556 * 557 * @deprecated Use {@link Builder} instead. 558 */ 559 @Deprecated 560 public void setLatestEventInfo(Context context, 561 CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) { 562 RemoteViews contentView = new RemoteViews(context.getPackageName(), 563 R.layout.status_bar_latest_event_content); 564 if (this.icon != 0) { 565 contentView.setImageViewResource(R.id.icon, this.icon); 566 } 567 if (contentTitle != null) { 568 contentView.setTextViewText(R.id.title, contentTitle); 569 } 570 if (contentText != null) { 571 contentView.setTextViewText(R.id.text, contentText); 572 } 573 if (this.when != 0) { 574 contentView.setLong(R.id.time, "setTime", when); 575 } 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 } 592 if (N != -1) { 593 sb.append(this.vibrate[N]); 594 } 595 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)); 611 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 } 616 sb.append(")"); 617 return sb.toString(); 618 } 619 620 public static class Builder { 621 private Context mContext; 622 623 private long mWhen; 624 private int mSmallIcon; 625 private int mSmallIconLevel; 626 private int mNumber; 627 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 667 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 677 public Builder setNumber(int number) { 678 mNumber = number; 679 return this; 680 } 681 682 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 724 public Builder setSound(Uri sound) { 725 mSound = sound; 726 mAudioStreamType = STREAM_DEFAULT; 727 return this; 728 } 729 730 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; 766 int moreFlags = 0; 767 if ((defaults & DEFAULT_LIGHTS) != 0) { 768 moreFlags |= FLAG_SHOW_LIGHTS; 769 } 770 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 781 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 809 private RemoteViews makeContentView() { 810 if (mContentView != null) { 811 return mContentView; 812 } else { 813 return makeRemoteViews(mLargeIcon == null 814 ? R.layout.status_bar_latest_event_content 815 : R.layout.status_bar_latest_event_content_large_icon); 816 } 817 } 818 819 private RemoteViews makeTickerView() { 820 if (mTickerView != null) { 821 return mTickerView; 822 } else { 823 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 } 830 } 831 } 832 833 public Notification getNotification() { 834 Notification n = new Notification(); 835 n.when = mWhen; 836 n.icon = mSmallIcon; 837 n.iconLevel = mSmallIconLevel; 838 n.number = mNumber; 839 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 } 857} 858