NotificationCompat.java revision 47702147608084fec16a50640da54b412c737b9c
1/* 2 * Copyright (C) 2012 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.support.v4.app; 18 19import android.app.Notification; 20import android.app.NotificationManager; 21import android.app.PendingIntent; 22import android.content.Context; 23import android.graphics.Bitmap; 24import android.media.AudioManager; 25import android.net.Uri; 26import android.os.Build; 27import android.os.Bundle; 28import android.widget.RemoteViews; 29import java.util.ArrayList; 30 31/** 32 * Helper for accessing features in {@link android.app.Notification} 33 * introduced after API level 4 in a backwards compatible fashion. 34 */ 35public class NotificationCompat { 36 /** 37 * Obsolete flag indicating high-priority notifications; use the priority field instead. 38 * 39 * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value. 40 */ 41 public static final int FLAG_HIGH_PRIORITY = 0x00000080; 42 43 /** 44 * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}. 45 * If your application does not prioritize its own notifications, 46 * use this value for all notifications. 47 */ 48 public static final int PRIORITY_DEFAULT = 0; 49 50 /** 51 * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 52 * for items that are less important. The UI may choose to show 53 * these items smaller, or at a different position in the list, 54 * compared with your app's {@link #PRIORITY_DEFAULT} items. 55 */ 56 public static final int PRIORITY_LOW = -1; 57 58 /** 59 * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)}; 60 * these items might not be shown to the user except under 61 * special circumstances, such as detailed notification logs. 62 */ 63 public static final int PRIORITY_MIN = -2; 64 65 /** 66 * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 67 * for more important notifications or alerts. The UI may choose 68 * to show these items larger, or at a different position in 69 * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items. 70 */ 71 public static final int PRIORITY_HIGH = 1; 72 73 /** 74 * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 75 * for your application's most important items that require the user's 76 * prompt attention or input. 77 */ 78 public static final int PRIORITY_MAX = 2; 79 80 private static final NotificationCompatImpl IMPL; 81 82 interface NotificationCompatImpl { 83 public Notification build(Builder b); 84 public Bundle getExtras(Notification n); 85 public boolean getLocalOnly(Notification n); 86 } 87 88 static class NotificationCompatImplBase implements NotificationCompatImpl { 89 @Override 90 public Notification build(Builder b) { 91 Notification result = b.mNotification; 92 result.setLatestEventInfo(b.mContext, b.mContentTitle, 93 b.mContentText, b.mContentIntent); 94 // translate high priority requests into legacy flag 95 if (b.mPriority > PRIORITY_DEFAULT) { 96 result.flags |= FLAG_HIGH_PRIORITY; 97 } 98 return result; 99 } 100 101 @Override 102 public Bundle getExtras(Notification n) { 103 return null; 104 } 105 106 @Override 107 public boolean getLocalOnly(Notification n) { 108 return false; 109 } 110 } 111 112 static class NotificationCompatImplGingerbread extends NotificationCompatImplBase { 113 @Override 114 public Notification build(Builder b) { 115 Notification result = b.mNotification; 116 result.setLatestEventInfo(b.mContext, b.mContentTitle, 117 b.mContentText, b.mContentIntent); 118 result = NotificationCompatGingerbread.add(result, b.mContext, 119 b.mContentTitle, b.mContentText, b.mContentIntent, b.mFullScreenIntent); 120 // translate high priority requests into legacy flag 121 if (b.mPriority > PRIORITY_DEFAULT) { 122 result.flags |= FLAG_HIGH_PRIORITY; 123 } 124 return result; 125 } 126 } 127 128 static class NotificationCompatImplHoneycomb extends NotificationCompatImplBase { 129 @Override 130 public Notification build(Builder b) { 131 return NotificationCompatHoneycomb.add(b.mContext, b.mNotification, 132 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 133 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon); 134 } 135 } 136 137 static class NotificationCompatImplIceCreamSandwich extends NotificationCompatImplBase { 138 @Override 139 public Notification build(Builder b) { 140 return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification, 141 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 142 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 143 b.mProgressMax, b.mProgress, b.mProgressIndeterminate); 144 } 145 } 146 147 static class NotificationCompatImplJellybean extends NotificationCompatImplBase { 148 @Override 149 public Notification build(Builder b) { 150 NotificationCompatJellybean.Builder builder = new NotificationCompatJellybean.Builder( 151 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 152 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 153 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 154 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras); 155 addActionsToBuilder(builder, b.mActions); 156 addStyleToBuilderJellybean(builder, b.mStyle); 157 return builder.build(); 158 } 159 160 @Override 161 public Bundle getExtras(Notification n) { 162 return NotificationCompatJellybean.getExtras(n); 163 } 164 165 @Override 166 public boolean getLocalOnly(Notification n) { 167 return NotificationCompatJellybean.getLocalOnly(n); 168 } 169 } 170 171 static class NotificationCompatImplKitKat extends NotificationCompatImplBase { 172 @Override 173 public Notification build(Builder b) { 174 NotificationCompatKitKat.Builder builder = new NotificationCompatKitKat.Builder( 175 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 176 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 177 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 178 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras); 179 addActionsToBuilder(builder, b.mActions); 180 addStyleToBuilderJellybean(builder, b.mStyle); 181 return builder.build(); 182 } 183 184 @Override 185 public Bundle getExtras(Notification n) { 186 return NotificationCompatKitKat.getExtras(n); 187 } 188 189 @Override 190 public boolean getLocalOnly(Notification n) { 191 return NotificationCompatKitKat.getLocalOnly(n); 192 } 193 } 194 195 static class NotificationCompatImplApi20 extends NotificationCompatImplBase { 196 @Override 197 public Notification build(Builder b) { 198 NotificationCompatApi20.Builder builder = new NotificationCompatApi20.Builder( 199 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 200 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 201 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 202 b.mUseChronometer, b.mPriority, b.mSubText, b.mLocalOnly, b.mExtras); 203 addActionsToBuilder(builder, b.mActions); 204 addStyleToBuilderJellybean(builder, b.mStyle); 205 return builder.build(); 206 } 207 208 @Override 209 public Bundle getExtras(Notification n) { 210 return NotificationCompatKitKat.getExtras(n); 211 } 212 213 @Override 214 public boolean getLocalOnly(Notification n) { 215 return NotificationCompatApi20.getLocalOnly(n); 216 } 217 } 218 219 private static void addActionsToBuilder(NotificationBuilderWithActions builder, 220 ArrayList<Action> actions) { 221 for (Action action : actions) { 222 builder.addAction(action.icon, action.title, action.actionIntent); 223 } 224 } 225 226 private static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder, 227 Style style) { 228 if (style != null) { 229 if (style instanceof BigTextStyle) { 230 BigTextStyle bigTextStyle = (BigTextStyle) style; 231 NotificationCompatJellybean.addBigTextStyle(builder, 232 bigTextStyle.mBigContentTitle, 233 bigTextStyle.mSummaryTextSet, 234 bigTextStyle.mSummaryText, 235 bigTextStyle.mBigText); 236 } else if (style instanceof InboxStyle) { 237 InboxStyle inboxStyle = (InboxStyle) style; 238 NotificationCompatJellybean.addInboxStyle(builder, 239 inboxStyle.mBigContentTitle, 240 inboxStyle.mSummaryTextSet, 241 inboxStyle.mSummaryText, 242 inboxStyle.mTexts); 243 } else if (style instanceof BigPictureStyle) { 244 BigPictureStyle bigPictureStyle = (BigPictureStyle) style; 245 NotificationCompatJellybean.addBigPictureStyle(builder, 246 bigPictureStyle.mBigContentTitle, 247 bigPictureStyle.mSummaryTextSet, 248 bigPictureStyle.mSummaryText, 249 bigPictureStyle.mPicture, 250 bigPictureStyle.mBigLargeIcon, 251 bigPictureStyle.mBigLargeIconSet); 252 } 253 } 254 } 255 256 static { 257 // TODO: Add NotificationCompatApi20 when SDK_INT is incremented. 258 if (Build.VERSION.SDK_INT >= 19) { 259 IMPL = new NotificationCompatImplKitKat(); 260 } else if (Build.VERSION.SDK_INT >= 16) { 261 IMPL = new NotificationCompatImplJellybean(); 262 } else if (Build.VERSION.SDK_INT >= 14) { 263 IMPL = new NotificationCompatImplIceCreamSandwich(); 264 } else if (Build.VERSION.SDK_INT >= 11) { 265 IMPL = new NotificationCompatImplHoneycomb(); 266 } else if (Build.VERSION.SDK_INT >= 9) { 267 IMPL = new NotificationCompatImplGingerbread(); 268 } else { 269 IMPL = new NotificationCompatImplBase(); 270 } 271 } 272 273 /** 274 * Builder class for {@link NotificationCompat} objects. Allows easier control over 275 * all the flags, as well as help constructing the typical notification layouts. 276 * <p> 277 * On platform versions that don't offer expanded notifications, methods that depend on 278 * expanded notifications have no effect. 279 * </p> 280 * <p> 281 * For example, action buttons won't appear on platforms prior to Android 4.1. Action 282 * buttons depend on expanded notifications, which are only available in Android 4.1 283 * and later. 284 * <p> 285 * For this reason, you should always ensure that UI controls in a notification are also 286 * available in an {@link android.app.Activity} in your app, and you should always start that 287 * {@link android.app.Activity} when users click the notification. To do this, use the 288 * {@link NotificationCompat.Builder#setContentIntent setContentIntent()} 289 * method. 290 * </p> 291 * 292 */ 293 public static class Builder { 294 Context mContext; 295 296 CharSequence mContentTitle; 297 CharSequence mContentText; 298 PendingIntent mContentIntent; 299 PendingIntent mFullScreenIntent; 300 RemoteViews mTickerView; 301 Bitmap mLargeIcon; 302 CharSequence mContentInfo; 303 int mNumber; 304 int mPriority; 305 boolean mUseChronometer; 306 Style mStyle; 307 CharSequence mSubText; 308 int mProgressMax; 309 int mProgress; 310 boolean mProgressIndeterminate; 311 ArrayList<Action> mActions = new ArrayList<Action>(); 312 boolean mLocalOnly = false; 313 Bundle mExtras; 314 315 Notification mNotification = new Notification(); 316 317 /** 318 * Constructor. 319 * 320 * Automatically sets the when field to {@link System#currentTimeMillis() 321 * System.currentTimeMillis()} and the audio stream to the 322 * {@link Notification#STREAM_DEFAULT}. 323 * 324 * @param context A {@link Context} that will be used to construct the 325 * RemoteViews. The Context will not be held past the lifetime of this 326 * Builder object. 327 */ 328 public Builder(Context context) { 329 mContext = context; 330 331 // Set defaults to match the defaults of a Notification 332 mNotification.when = System.currentTimeMillis(); 333 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 334 mPriority = PRIORITY_DEFAULT; 335 } 336 337 /** 338 * Set the time that the event occurred. Notifications in the panel are 339 * sorted by this time. 340 */ 341 public Builder setWhen(long when) { 342 mNotification.when = when; 343 return this; 344 } 345 346 /** 347 * Show the {@link Notification#when} field as a stopwatch. 348 * 349 * Instead of presenting <code>when</code> as a timestamp, the notification will show an 350 * automatically updating display of the minutes and seconds since <code>when</code>. 351 * 352 * Useful when showing an elapsed time (like an ongoing phone call). 353 * 354 * @see android.widget.Chronometer 355 * @see Notification#when 356 */ 357 public Builder setUsesChronometer(boolean b) { 358 mUseChronometer = b; 359 return this; 360 } 361 362 /** 363 * Set the small icon to use in the notification layouts. Different classes of devices 364 * may return different sizes. See the UX guidelines for more information on how to 365 * design these icons. 366 * 367 * @param icon A resource ID in the application's package of the drawble to use. 368 */ 369 public Builder setSmallIcon(int icon) { 370 mNotification.icon = icon; 371 return this; 372 } 373 374 /** 375 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 376 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 377 * LevelListDrawable}. 378 * 379 * @param icon A resource ID in the application's package of the drawble to use. 380 * @param level The level to use for the icon. 381 * 382 * @see android.graphics.drawable.LevelListDrawable 383 */ 384 public Builder setSmallIcon(int icon, int level) { 385 mNotification.icon = icon; 386 mNotification.iconLevel = level; 387 return this; 388 } 389 390 /** 391 * Set the title (first row) of the notification, in a standard notification. 392 */ 393 public Builder setContentTitle(CharSequence title) { 394 mContentTitle = title; 395 return this; 396 } 397 398 /** 399 * Set the text (second row) of the notification, in a standard notification. 400 */ 401 public Builder setContentText(CharSequence text) { 402 mContentText = text; 403 return this; 404 } 405 406 /** 407 * Set the third line of text in the platform notification template. 408 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; 409 * they occupy the same location in the standard template. 410 * <br> 411 * If the platform does not provide large-format notifications, this method has no effect. 412 * The third line of text only appears in expanded view. 413 * <br> 414 */ 415 public Builder setSubText(CharSequence text) { 416 mSubText = text; 417 return this; 418 } 419 420 /** 421 * Set the large number at the right-hand side of the notification. This is 422 * equivalent to setContentInfo, although it might show the number in a different 423 * font size for readability. 424 */ 425 public Builder setNumber(int number) { 426 mNumber = number; 427 return this; 428 } 429 430 /** 431 * Set the large text at the right-hand side of the notification. 432 */ 433 public Builder setContentInfo(CharSequence info) { 434 mContentInfo = info; 435 return this; 436 } 437 438 /** 439 * Set the progress this notification represents, which may be 440 * represented as a {@link android.widget.ProgressBar}. 441 */ 442 public Builder setProgress(int max, int progress, boolean indeterminate) { 443 mProgressMax = max; 444 mProgress = progress; 445 mProgressIndeterminate = indeterminate; 446 return this; 447 } 448 449 /** 450 * Supply a custom RemoteViews to use instead of the standard one. 451 */ 452 public Builder setContent(RemoteViews views) { 453 mNotification.contentView = views; 454 return this; 455 } 456 457 /** 458 * Supply a {@link PendingIntent} to send when the notification is clicked. 459 * If you do not supply an intent, you can now add PendingIntents to individual 460 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 461 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to 462 * read {@link Notification#contentIntent Notification.contentIntent} for 463 * how to correctly use this. 464 */ 465 public Builder setContentIntent(PendingIntent intent) { 466 mContentIntent = intent; 467 return this; 468 } 469 470 /** 471 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 472 * directly from the notification panel. For example, this intent is sent when the user 473 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 474 * intent is not sent when the application calls {@link NotificationManager#cancel 475 * NotificationManager.cancel(int)}. 476 */ 477 public Builder setDeleteIntent(PendingIntent intent) { 478 mNotification.deleteIntent = intent; 479 return this; 480 } 481 482 /** 483 * An intent to launch instead of posting the notification to the status bar. 484 * Only for use with extremely high-priority notifications demanding the user's 485 * <strong>immediate</strong> attention, such as an incoming phone call or 486 * alarm clock that the user has explicitly set to a particular time. 487 * If this facility is used for something else, please give the user an option 488 * to turn it off and use a normal notification, as this can be extremely 489 * disruptive. 490 * 491 * @param intent The pending intent to launch. 492 * @param highPriority Passing true will cause this notification to be sent 493 * even if other notifications are suppressed. 494 */ 495 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 496 mFullScreenIntent = intent; 497 setFlag(FLAG_HIGH_PRIORITY, highPriority); 498 return this; 499 } 500 501 /** 502 * Set the text that is displayed in the status bar when the notification first 503 * arrives. 504 */ 505 public Builder setTicker(CharSequence tickerText) { 506 mNotification.tickerText = tickerText; 507 return this; 508 } 509 510 /** 511 * Set the text that is displayed in the status bar when the notification first 512 * arrives, and also a RemoteViews object that may be displayed instead on some 513 * devices. 514 */ 515 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 516 mNotification.tickerText = tickerText; 517 mTickerView = views; 518 return this; 519 } 520 521 /** 522 * Set the large icon that is shown in the ticker and notification. 523 */ 524 public Builder setLargeIcon(Bitmap icon) { 525 mLargeIcon = icon; 526 return this; 527 } 528 529 /** 530 * Set the sound to play. It will play on the default stream. 531 */ 532 public Builder setSound(Uri sound) { 533 mNotification.sound = sound; 534 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 535 return this; 536 } 537 538 /** 539 * Set the sound to play. It will play on the stream you supply. 540 * 541 * @see Notification#STREAM_DEFAULT 542 * @see AudioManager for the <code>STREAM_</code> constants. 543 */ 544 public Builder setSound(Uri sound, int streamType) { 545 mNotification.sound = sound; 546 mNotification.audioStreamType = streamType; 547 return this; 548 } 549 550 /** 551 * Set the vibration pattern to use. 552 * 553 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 554 * parameter. 555 */ 556 public Builder setVibrate(long[] pattern) { 557 mNotification.vibrate = pattern; 558 return this; 559 } 560 561 /** 562 * Set the argb value that you would like the LED on the device to blnk, as well as the 563 * rate. The rate is specified in terms of the number of milliseconds to be on 564 * and then the number of milliseconds to be off. 565 */ 566 public Builder setLights(int argb, int onMs, int offMs) { 567 mNotification.ledARGB = argb; 568 mNotification.ledOnMS = onMs; 569 mNotification.ledOffMS = offMs; 570 boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0; 571 mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) | 572 (showLights ? Notification.FLAG_SHOW_LIGHTS : 0); 573 return this; 574 } 575 576 /** 577 * Set whether this is an ongoing notification. 578 * 579 * <p>Ongoing notifications differ from regular notifications in the following ways: 580 * <ul> 581 * <li>Ongoing notifications are sorted above the regular notifications in the 582 * notification panel.</li> 583 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 584 * by the "Clear all" button. 585 * </ul> 586 */ 587 public Builder setOngoing(boolean ongoing) { 588 setFlag(Notification.FLAG_ONGOING_EVENT, ongoing); 589 return this; 590 } 591 592 /** 593 * Set this flag if you would only like the sound, vibrate 594 * and ticker to be played if the notification is not already showing. 595 */ 596 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 597 setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 598 return this; 599 } 600 601 /** 602 * Setting this flag will make it so the notification is automatically 603 * canceled when the user clicks it in the panel. The PendingIntent 604 * set with {@link #setDeleteIntent} will be broadcast when the notification 605 * is canceled. 606 */ 607 public Builder setAutoCancel(boolean autoCancel) { 608 setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel); 609 return this; 610 } 611 612 /** 613 * Set whether or not this notification is only relevant to the current device. 614 * 615 * <p>Some notifications can be bridged to other devices for remote display. 616 * This hint can be set to recommend this notification not be bridged. 617 */ 618 public Builder setLocalOnly(boolean b) { 619 mLocalOnly = b; 620 return this; 621 } 622 623 /** 624 * Set the default notification options that will be used. 625 * <p> 626 * The value should be one or more of the following fields combined with 627 * bitwise-or: 628 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE}, 629 * {@link Notification#DEFAULT_LIGHTS}. 630 * <p> 631 * For all default values, use {@link Notification#DEFAULT_ALL}. 632 */ 633 public Builder setDefaults(int defaults) { 634 mNotification.defaults = defaults; 635 if ((defaults & Notification.DEFAULT_LIGHTS) != 0) { 636 mNotification.flags |= Notification.FLAG_SHOW_LIGHTS; 637 } 638 return this; 639 } 640 641 private void setFlag(int mask, boolean value) { 642 if (value) { 643 mNotification.flags |= mask; 644 } else { 645 mNotification.flags &= ~mask; 646 } 647 } 648 649 /** 650 * Set the relative priority for this notification. 651 * 652 * Priority is an indication of how much of the user's 653 * valuable attention should be consumed by this 654 * notification. Low-priority notifications may be hidden from 655 * the user in certain situations, while the user might be 656 * interrupted for a higher-priority notification. 657 * The system sets a notification's priority based on various factors including the 658 * setPriority value. The effect may differ slightly on different platforms. 659 */ 660 public Builder setPriority(int pri) { 661 mPriority = pri; 662 return this; 663 } 664 665 /** 666 * Merge additional metadata into this notification. 667 * 668 * <p>Values within the Bundle will replace existing extras values in this Builder. 669 * 670 * @see Notification#extras 671 */ 672 public Builder addExtras(Bundle bag) { 673 if (mExtras == null) { 674 mExtras = new Bundle(bag); 675 } else { 676 mExtras.putAll(bag); 677 } 678 return this; 679 } 680 681 /** 682 * Set metadata for this notification. 683 * 684 * <p>A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's 685 * current contents are copied into the Notification each time {@link #build()} is 686 * called. 687 * 688 * <p>Replaces any existing extras values with those from the provided Bundle. 689 * Use {@link #addExtras} to merge in metadata instead. 690 * 691 * @see Notification#extras 692 */ 693 public Builder setExtras(Bundle bag) { 694 mExtras = bag; 695 return this; 696 } 697 698 /** 699 * Get the current metadata Bundle used by this notification Builder. 700 * 701 * <p>The returned Bundle is shared with this Builder. 702 * 703 * <p>The current contents of this Bundle are copied into the Notification each time 704 * {@link #build()} is called. 705 * 706 * @see Notification#extras 707 */ 708 public Bundle getExtras() { 709 if (mExtras == null) { 710 mExtras = new Bundle(); 711 } 712 return mExtras; 713 } 714 715 /** 716 * Add an action to this notification. Actions are typically displayed by 717 * the system as a button adjacent to the notification content. 718 * <br> 719 * Action buttons won't appear on platforms prior to Android 4.1. Action 720 * buttons depend on expanded notifications, which are only available in Android 4.1 721 * and later. To ensure that an action button's functionality is always available, first 722 * implement the functionality in the {@link android.app.Activity} that starts when a user 723 * clicks the notification (see {@link #setContentIntent setContentIntent()}), and then 724 * enhance the notification by implementing the same functionality with 725 * {@link #addAction addAction()}. 726 * 727 * @param icon Resource ID of a drawable that represents the action. 728 * @param title Text describing the action. 729 * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked. 730 */ 731 public Builder addAction(int icon, CharSequence title, PendingIntent intent) { 732 mActions.add(new Action(icon, title, intent)); 733 return this; 734 } 735 736 /** 737 * Add a rich notification style to be applied at build time. 738 * <br> 739 * If the platform does not provide rich notification styles, this method has no effect. The 740 * user will always see the normal notification style. 741 * 742 * @param style Object responsible for modifying the notification style. 743 */ 744 public Builder setStyle(Style style) { 745 if (mStyle != style) { 746 mStyle = style; 747 if (mStyle != null) { 748 mStyle.setBuilder(this); 749 } 750 } 751 return this; 752 } 753 754 /** 755 * @deprecated Use {@link #build()} instead. 756 */ 757 @Deprecated 758 public Notification getNotification() { 759 return IMPL.build(this); 760 } 761 762 /** 763 * Combine all of the options that have been set and return a new {@link Notification} 764 * object. 765 */ 766 public Notification build() { 767 return IMPL.build(this); 768 } 769 } 770 771 /** 772 * An object that can apply a rich notification style to a {@link Notification.Builder} 773 * object. 774 * <br> 775 * If the platform does not provide rich notification styles, methods in this class have no 776 * effect. 777 */ 778 public static abstract class Style { 779 Builder mBuilder; 780 CharSequence mBigContentTitle; 781 CharSequence mSummaryText; 782 boolean mSummaryTextSet = false; 783 784 public void setBuilder(Builder builder) { 785 if (mBuilder != builder) { 786 mBuilder = builder; 787 if (mBuilder != null) { 788 mBuilder.setStyle(this); 789 } 790 } 791 } 792 793 public Notification build() { 794 Notification notification = null; 795 if (mBuilder != null) { 796 notification = mBuilder.build(); 797 } 798 return notification; 799 } 800 } 801 802 /** 803 * Helper class for generating large-format notifications that include a large image attachment. 804 * <br> 805 * If the platform does not provide large-format notifications, this method has no effect. The 806 * user will always see the normal notification view. 807 * <br> 808 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 809 * <pre class="prettyprint"> 810 * Notification noti = new Notification.Builder() 811 * .setContentTitle("New photo from " + sender.toString()) 812 * .setContentText(subject) 813 * .setSmallIcon(R.drawable.new_post) 814 * .setLargeIcon(aBitmap) 815 * .setStyle(new Notification.BigPictureStyle() 816 * .bigPicture(aBigBitmap)) 817 * .build(); 818 * </pre> 819 * 820 * @see Notification#bigContentView 821 */ 822 public static class BigPictureStyle extends Style { 823 Bitmap mPicture; 824 Bitmap mBigLargeIcon; 825 boolean mBigLargeIconSet; 826 827 public BigPictureStyle() { 828 } 829 830 public BigPictureStyle(Builder builder) { 831 setBuilder(builder); 832 } 833 834 /** 835 * Overrides ContentTitle in the big form of the template. 836 * This defaults to the value passed to setContentTitle(). 837 */ 838 public BigPictureStyle setBigContentTitle(CharSequence title) { 839 mBigContentTitle = title; 840 return this; 841 } 842 843 /** 844 * Set the first line of text after the detail section in the big form of the template. 845 */ 846 public BigPictureStyle setSummaryText(CharSequence cs) { 847 mSummaryText = cs; 848 mSummaryTextSet = true; 849 return this; 850 } 851 852 /** 853 * Provide the bitmap to be used as the payload for the BigPicture notification. 854 */ 855 public BigPictureStyle bigPicture(Bitmap b) { 856 mPicture = b; 857 return this; 858 } 859 860 /** 861 * Override the large icon when the big notification is shown. 862 */ 863 public BigPictureStyle bigLargeIcon(Bitmap b) { 864 mBigLargeIcon = b; 865 mBigLargeIconSet = true; 866 return this; 867 } 868 } 869 870 /** 871 * Helper class for generating large-format notifications that include a lot of text. 872 * 873 * <br> 874 * If the platform does not provide large-format notifications, this method has no effect. The 875 * user will always see the normal notification view. 876 * <br> 877 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 878 * <pre class="prettyprint"> 879 * Notification noti = new Notification.Builder() 880 * .setContentTitle("New mail from " + sender.toString()) 881 * .setContentText(subject) 882 * .setSmallIcon(R.drawable.new_mail) 883 * .setLargeIcon(aBitmap) 884 * .setStyle(new Notification.BigTextStyle() 885 * .bigText(aVeryLongString)) 886 * .build(); 887 * </pre> 888 * 889 * @see Notification#bigContentView 890 */ 891 public static class BigTextStyle extends Style { 892 CharSequence mBigText; 893 894 public BigTextStyle() { 895 } 896 897 public BigTextStyle(Builder builder) { 898 setBuilder(builder); 899 } 900 901 /** 902 * Overrides ContentTitle in the big form of the template. 903 * This defaults to the value passed to setContentTitle(). 904 */ 905 public BigTextStyle setBigContentTitle(CharSequence title) { 906 mBigContentTitle = title; 907 return this; 908 } 909 910 /** 911 * Set the first line of text after the detail section in the big form of the template. 912 */ 913 public BigTextStyle setSummaryText(CharSequence cs) { 914 mSummaryText = cs; 915 mSummaryTextSet = true; 916 return this; 917 } 918 919 /** 920 * Provide the longer text to be displayed in the big form of the 921 * template in place of the content text. 922 */ 923 public BigTextStyle bigText(CharSequence cs) { 924 mBigText = cs; 925 return this; 926 } 927 } 928 929 /** 930 * Helper class for generating large-format notifications that include a list of (up to 5) strings. 931 * 932 * <br> 933 * If the platform does not provide large-format notifications, this method has no effect. The 934 * user will always see the normal notification view. 935 * <br> 936 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 937 * <pre class="prettyprint"> 938 * Notification noti = new Notification.Builder() 939 * .setContentTitle("5 New mails from " + sender.toString()) 940 * .setContentText(subject) 941 * .setSmallIcon(R.drawable.new_mail) 942 * .setLargeIcon(aBitmap) 943 * .setStyle(new Notification.InboxStyle() 944 * .addLine(str1) 945 * .addLine(str2) 946 * .setContentTitle("") 947 * .setSummaryText("+3 more")) 948 * .build(); 949 * </pre> 950 * 951 * @see Notification#bigContentView 952 */ 953 public static class InboxStyle extends Style { 954 ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(); 955 956 public InboxStyle() { 957 } 958 959 public InboxStyle(Builder builder) { 960 setBuilder(builder); 961 } 962 963 /** 964 * Overrides ContentTitle in the big form of the template. 965 * This defaults to the value passed to setContentTitle(). 966 */ 967 public InboxStyle setBigContentTitle(CharSequence title) { 968 mBigContentTitle = title; 969 return this; 970 } 971 972 /** 973 * Set the first line of text after the detail section in the big form of the template. 974 */ 975 public InboxStyle setSummaryText(CharSequence cs) { 976 mSummaryText = cs; 977 mSummaryTextSet = true; 978 return this; 979 } 980 981 /** 982 * Append a line to the digest section of the Inbox notification. 983 */ 984 public InboxStyle addLine(CharSequence cs) { 985 mTexts.add(cs); 986 return this; 987 } 988 } 989 990 public static class Action { 991 public int icon; 992 public CharSequence title; 993 public PendingIntent actionIntent; 994 995 public Action(int icon_, CharSequence title_, PendingIntent intent_) { 996 this.icon = icon_; 997 this.title = title_; 998 this.actionIntent = intent_; 999 } 1000 } 1001 1002 /** 1003 * Gets the {@link Notification#extras} field from a notification in a backwards 1004 * compatible manner. Extras field was supported from JellyBean (Api level 16) 1005 * forwards. This function will return null on older api levels. 1006 */ 1007 public static Bundle getExtras(Notification notif) { 1008 return IMPL.getExtras(notif); 1009 } 1010 1011 /** 1012 * Get whether or not this notification is only relevant to the current device. 1013 * 1014 * <p>Some notifications can be bridged to other devices for remote display. 1015 * If this hint is set, it is recommend that this notification not be bridged. 1016 */ 1017 public static boolean getLocalOnly(Notification notif) { 1018 return IMPL.getLocalOnly(notif); 1019 } 1020} 1021