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