NotificationCompat.java revision 080df8ffb0920eccb300baa39180eb956a000a53
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.widget.RemoteViews; 28import java.util.ArrayList; 29 30/** 31 * Helper for accessing features in {@link android.app.Notification} 32 * introduced after API level 4 in a backwards compatible fashion. 33 */ 34public class NotificationCompat { 35 /** 36 * Obsolete flag indicating high-priority notifications; use the priority field instead. 37 * 38 * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value. 39 */ 40 public static final int FLAG_HIGH_PRIORITY = 0x00000080; 41 42 /** 43 * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}. 44 * If your application does not prioritize its own notifications, 45 * use this value for all notifications. 46 */ 47 public static final int PRIORITY_DEFAULT = 0; 48 49 /** 50 * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 51 * for items that are less important. The UI may choose to show 52 * these items smaller, or at a different position in the list, 53 * compared with your app's {@link #PRIORITY_DEFAULT} items. 54 */ 55 public static final int PRIORITY_LOW = -1; 56 57 /** 58 * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)}; 59 * these items might not be shown to the user except under 60 * special circumstances, such as detailed notification logs. 61 */ 62 public static final int PRIORITY_MIN = -2; 63 64 /** 65 * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 66 * for more important notifications or alerts. The UI may choose 67 * to show these items larger, or at a different position in 68 * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items. 69 */ 70 public static final int PRIORITY_HIGH = 1; 71 72 /** 73 * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)}, 74 * for your application's most important items that require the user's 75 * prompt attention or input. 76 */ 77 public static final int PRIORITY_MAX = 2; 78 79 private static final NotificationCompatImpl IMPL; 80 81 interface NotificationCompatImpl { 82 public Notification build(Builder b); 83 } 84 85 static class NotificationCompatImplBase implements NotificationCompatImpl { 86 public Notification build(Builder b) { 87 Notification result = (Notification) b.mNotification; 88 result.setLatestEventInfo(b.mContext, b.mContentTitle, 89 b.mContentText, b.mContentIntent); 90 // translate high priority requests into legacy flag 91 if (b.mPriority > PRIORITY_DEFAULT) { 92 result.flags |= FLAG_HIGH_PRIORITY; 93 } 94 return result; 95 } 96 } 97 98 static class NotificationCompatImplHoneycomb implements NotificationCompatImpl { 99 public Notification build(Builder b) { 100 return NotificationCompatHoneycomb.add(b.mContext, b.mNotification, 101 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 102 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon); 103 } 104 } 105 106 static class NotificationCompatImplIceCreamSandwich implements NotificationCompatImpl { 107 public Notification build(Builder b) { 108 return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification, 109 b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView, 110 b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 111 b.mProgressMax, b.mProgress, b.mProgressIndeterminate); 112 } 113 } 114 115 static class NotificationCompatImplJellybean implements NotificationCompatImpl { 116 public Notification build(Builder b) { 117 NotificationCompatJellybean jbBuilder = new NotificationCompatJellybean( 118 b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo, 119 b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon, 120 b.mProgressMax, b.mProgress, b.mProgressIndeterminate, 121 b.mUseChronometer, b.mPriority, b.mSubText); 122 for (Action action: b.mActions) { 123 jbBuilder.addAction(action.icon, action.title, action.actionIntent); 124 } 125 if (b.mStyle != null) { 126 if (b.mStyle instanceof BigTextStyle) { 127 BigTextStyle style = (BigTextStyle) b.mStyle; 128 jbBuilder.addBigTextStyle(style.mBigContentTitle, 129 style.mSummaryTextSet, 130 style.mSummaryText, 131 style.mBigText); 132 } else if (b.mStyle instanceof InboxStyle) { 133 InboxStyle style = (InboxStyle) b.mStyle; 134 jbBuilder.addInboxStyle(style.mBigContentTitle, 135 style.mSummaryTextSet, 136 style.mSummaryText, 137 style.mTexts); 138 } else if (b.mStyle instanceof BigPictureStyle) { 139 BigPictureStyle style = (BigPictureStyle) b.mStyle; 140 jbBuilder.addBigPictureStyle(style.mBigContentTitle, 141 style.mSummaryTextSet, 142 style.mSummaryText, 143 style.mPicture); 144 } 145 } 146 return(jbBuilder.build()); 147 } 148 } 149 150 static { 151 if (Build.VERSION.SDK_INT >= 16) { 152 IMPL = new NotificationCompatImplJellybean(); 153 } else if (Build.VERSION.SDK_INT >= 14) { 154 IMPL = new NotificationCompatImplIceCreamSandwich(); 155 } else if (Build.VERSION.SDK_INT >= 11) { 156 IMPL = new NotificationCompatImplHoneycomb(); 157 } else { 158 IMPL = new NotificationCompatImplBase(); 159 } 160 } 161 162 /** 163 * Builder class for {@link Notification} objects. Allows easier control over 164 * all the flags, as well as help constructing the typical notification layouts. 165 */ 166 public static class Builder { 167 Context mContext; 168 169 CharSequence mContentTitle; 170 CharSequence mContentText; 171 PendingIntent mContentIntent; 172 PendingIntent mFullScreenIntent; 173 RemoteViews mTickerView; 174 Bitmap mLargeIcon; 175 CharSequence mContentInfo; 176 int mNumber; 177 int mPriority; 178 boolean mUseChronometer; 179 Style mStyle; 180 CharSequence mSubText; 181 int mProgressMax; 182 int mProgress; 183 boolean mProgressIndeterminate; 184 ArrayList<Action> mActions = new ArrayList<Action>(); 185 186 Notification mNotification = new Notification(); 187 188 /** 189 * Constructor. 190 * 191 * Automatically sets the when field to {@link System#currentTimeMillis() 192 * System.currentTimeMillis()} and the audio stream to the 193 * {@link Notification#STREAM_DEFAULT}. 194 * 195 * @param context A {@link Context} that will be used to construct the 196 * RemoteViews. The Context will not be held past the lifetime of this 197 * Builder object. 198 */ 199 public Builder(Context context) { 200 mContext = context; 201 202 // Set defaults to match the defaults of a Notification 203 mNotification.when = System.currentTimeMillis(); 204 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 205 mPriority = PRIORITY_DEFAULT; 206 } 207 208 /** 209 * Set the time that the event occurred. Notifications in the panel are 210 * sorted by this time. 211 */ 212 public Builder setWhen(long when) { 213 mNotification.when = when; 214 return this; 215 } 216 217 /** 218 * Show the {@link Notification#when} field as a stopwatch. 219 * 220 * Instead of presenting <code>when</code> as a timestamp, the notification will show an 221 * automatically updating display of the minutes and seconds since <code>when</code>. 222 * 223 * Useful when showing an elapsed time (like an ongoing phone call). 224 * 225 * @see android.widget.Chronometer 226 * @see Notification#when 227 */ 228 public Builder setUsesChronometer(boolean b) { 229 mUseChronometer = b; 230 return this; 231 } 232 233 /** 234 * Set the small icon to use in the notification layouts. Different classes of devices 235 * may return different sizes. See the UX guidelines for more information on how to 236 * design these icons. 237 * 238 * @param icon A resource ID in the application's package of the drawble to use. 239 */ 240 public Builder setSmallIcon(int icon) { 241 mNotification.icon = icon; 242 return this; 243 } 244 245 /** 246 * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional 247 * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable 248 * LevelListDrawable}. 249 * 250 * @param icon A resource ID in the application's package of the drawble to use. 251 * @param level The level to use for the icon. 252 * 253 * @see android.graphics.drawable.LevelListDrawable 254 */ 255 public Builder setSmallIcon(int icon, int level) { 256 mNotification.icon = icon; 257 mNotification.iconLevel = level; 258 return this; 259 } 260 261 /** 262 * Set the title (first row) of the notification, in a standard notification. 263 */ 264 public Builder setContentTitle(CharSequence title) { 265 mContentTitle = title; 266 return this; 267 } 268 269 /** 270 * Set the text (second row) of the notification, in a standard notification. 271 */ 272 public Builder setContentText(CharSequence text) { 273 mContentText = text; 274 return this; 275 } 276 277 /** 278 * Set the third line of text in the platform notification template. 279 * Don't use if you're also using {@link #setProgress(int, int, boolean)}; 280 * they occupy the same location in the standard template. 281 */ 282 public Builder setSubText(CharSequence text) { 283 mSubText = text; 284 return this; 285 } 286 287 /** 288 * Set the large number at the right-hand side of the notification. This is 289 * equivalent to setContentInfo, although it might show the number in a different 290 * font size for readability. 291 */ 292 public Builder setNumber(int number) { 293 mNumber = number; 294 return this; 295 } 296 297 /** 298 * Set the large text at the right-hand side of the notification. 299 */ 300 public Builder setContentInfo(CharSequence info) { 301 mContentInfo = info; 302 return this; 303 } 304 305 /** 306 * Set the progress this notification represents, which may be 307 * represented as a {@link android.widget.ProgressBar}. 308 */ 309 public Builder setProgress(int max, int progress, boolean indeterminate) { 310 mProgressMax = max; 311 mProgress = progress; 312 mProgressIndeterminate = indeterminate; 313 return this; 314 } 315 316 /** 317 * Supply a custom RemoteViews to use instead of the standard one. 318 */ 319 public Builder setContent(RemoteViews views) { 320 mNotification.contentView = views; 321 return this; 322 } 323 324 /** 325 * Supply a {@link PendingIntent} to send when the notification is clicked. 326 * If you do not supply an intent, you can now add PendingIntents to individual 327 * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent 328 * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to 329 * read {@link Notification#contentIntent Notification.contentIntent} for 330 * how to correctly use this. 331 */ 332 public Builder setContentIntent(PendingIntent intent) { 333 mContentIntent = intent; 334 return this; 335 } 336 337 /** 338 * Supply a {@link PendingIntent} to send when the notification is cleared by the user 339 * directly from the notification panel. For example, this intent is sent when the user 340 * clicks the "Clear all" button, or the individual "X" buttons on notifications. This 341 * intent is not sent when the application calls {@link NotificationManager#cancel 342 * NotificationManager.cancel(int)}. 343 */ 344 public Builder setDeleteIntent(PendingIntent intent) { 345 mNotification.deleteIntent = intent; 346 return this; 347 } 348 349 /** 350 * An intent to launch instead of posting the notification to the status bar. 351 * Only for use with extremely high-priority notifications demanding the user's 352 * <strong>immediate</strong> attention, such as an incoming phone call or 353 * alarm clock that the user has explicitly set to a particular time. 354 * If this facility is used for something else, please give the user an option 355 * to turn it off and use a normal notification, as this can be extremely 356 * disruptive. 357 * 358 * @param intent The pending intent to launch. 359 * @param highPriority Passing true will cause this notification to be sent 360 * even if other notifications are suppressed. 361 */ 362 public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) { 363 mFullScreenIntent = intent; 364 setFlag(FLAG_HIGH_PRIORITY, highPriority); 365 return this; 366 } 367 368 /** 369 * Set the text that is displayed in the status bar when the notification first 370 * arrives. 371 */ 372 public Builder setTicker(CharSequence tickerText) { 373 mNotification.tickerText = tickerText; 374 return this; 375 } 376 377 /** 378 * Set the text that is displayed in the status bar when the notification first 379 * arrives, and also a RemoteViews object that may be displayed instead on some 380 * devices. 381 */ 382 public Builder setTicker(CharSequence tickerText, RemoteViews views) { 383 mNotification.tickerText = tickerText; 384 mTickerView = views; 385 return this; 386 } 387 388 /** 389 * Set the large icon that is shown in the ticker and notification. 390 */ 391 public Builder setLargeIcon(Bitmap icon) { 392 mLargeIcon = icon; 393 return this; 394 } 395 396 /** 397 * Set the sound to play. It will play on the default stream. 398 */ 399 public Builder setSound(Uri sound) { 400 mNotification.sound = sound; 401 mNotification.audioStreamType = Notification.STREAM_DEFAULT; 402 return this; 403 } 404 405 /** 406 * Set the sound to play. It will play on the stream you supply. 407 * 408 * @see #STREAM_DEFAULT 409 * @see AudioManager for the <code>STREAM_</code> constants. 410 */ 411 public Builder setSound(Uri sound, int streamType) { 412 mNotification.sound = sound; 413 mNotification.audioStreamType = streamType; 414 return this; 415 } 416 417 /** 418 * Set the vibration pattern to use. 419 * 420 * @see android.os.Vibrator for a discussion of the <code>pattern</code> 421 * parameter. 422 */ 423 public Builder setVibrate(long[] pattern) { 424 mNotification.vibrate = pattern; 425 return this; 426 } 427 428 /** 429 * Set the argb value that you would like the LED on the device to blnk, as well as the 430 * rate. The rate is specified in terms of the number of milliseconds to be on 431 * and then the number of milliseconds to be off. 432 */ 433 public Builder setLights(int argb, int onMs, int offMs) { 434 mNotification.ledARGB = argb; 435 mNotification.ledOnMS = onMs; 436 mNotification.ledOffMS = offMs; 437 boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0; 438 mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) | 439 (showLights ? Notification.FLAG_SHOW_LIGHTS : 0); 440 return this; 441 } 442 443 /** 444 * Set whether this is an ongoing notification. 445 * 446 * <p>Ongoing notifications differ from regular notifications in the following ways: 447 * <ul> 448 * <li>Ongoing notifications are sorted above the regular notifications in the 449 * notification panel.</li> 450 * <li>Ongoing notifications do not have an 'X' close button, and are not affected 451 * by the "Clear all" button. 452 * </ul> 453 */ 454 public Builder setOngoing(boolean ongoing) { 455 setFlag(Notification.FLAG_ONGOING_EVENT, ongoing); 456 return this; 457 } 458 459 /** 460 * Set this flag if you would only like the sound, vibrate 461 * and ticker to be played if the notification is not already showing. 462 */ 463 public Builder setOnlyAlertOnce(boolean onlyAlertOnce) { 464 setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce); 465 return this; 466 } 467 468 /** 469 * Setting this flag will make it so the notification is automatically 470 * canceled when the user clicks it in the panel. The PendingIntent 471 * set with {@link #setDeleteIntent} will be broadcast when the notification 472 * is canceled. 473 */ 474 public Builder setAutoCancel(boolean autoCancel) { 475 setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel); 476 return this; 477 } 478 479 /** 480 * Set the default notification options that will be used. 481 * <p> 482 * The value should be one or more of the following fields combined with 483 * bitwise-or: 484 * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE}, 485 * {@link Notification#DEFAULT_LIGHTS}. 486 * <p> 487 * For all default values, use {@link Notification#DEFAULT_ALL}. 488 */ 489 public Builder setDefaults(int defaults) { 490 mNotification.defaults = defaults; 491 if ((defaults & Notification.DEFAULT_LIGHTS) != 0) { 492 mNotification.flags |= Notification.FLAG_SHOW_LIGHTS; 493 } 494 return this; 495 } 496 497 private void setFlag(int mask, boolean value) { 498 if (value) { 499 mNotification.flags |= mask; 500 } else { 501 mNotification.flags &= ~mask; 502 } 503 } 504 505 /** 506 * Set the relative priority for this notification. 507 * 508 * Priority is an indication of how much of the user's 509 * valuable attention should be consumed by this 510 * notification. Low-priority notifications may be hidden from 511 * the user in certain situations, while the user might be 512 * interrupted for a higher-priority notification. The system 513 * will make a determination about how to interpret 514 * notification priority as described in MUMBLE MUMBLE. 515 */ 516 public Builder setPriority(int pri) { 517 mPriority = pri; 518 return this; 519 } 520 521 /** 522 * Add an action to this notification. Actions are typically displayed by 523 * the system as a button adjacent to the notification content. 524 * 525 * @param icon Resource ID of a drawable that represents the action. 526 * @param title Text describing the action. 527 * @param intent PendingIntent to be fired when the action is invoked. 528 */ 529 public Builder addAction(int icon, CharSequence title, PendingIntent intent) { 530 mActions.add(new Action(icon, title, intent)); 531 return this; 532 } 533 534 /** 535 * Add a rich notification style to be applied at build time. 536 * 537 * @param style Object responsible for modifying the notification style. 538 */ 539 public Builder setStyle(Style style) { 540 if (mStyle != style) { 541 mStyle = style; 542 if (mStyle != null) { 543 mStyle.setBuilder(this); 544 } 545 } 546 return this; 547 } 548 549 /** 550 * @deprecated Use {@link #build()} instead. 551 */ 552 @Deprecated 553 public Notification getNotification() { 554 return (Notification) IMPL.build(this); 555 } 556 557 /** 558 * Combine all of the options that have been set and return a new {@link Notification} 559 * object. 560 */ 561 public Notification build() { 562 return (Notification) IMPL.build(this); 563 } 564 } 565 566 /** 567 * An object that can apply a rich notification style to a {@link Notification.Builder} 568 * object. 569 */ 570 public static abstract class Style 571 { 572 Builder mBuilder; 573 CharSequence mBigContentTitle; 574 CharSequence mSummaryText; 575 boolean mSummaryTextSet = false; 576 577 public void setBuilder(Builder builder) { 578 if (mBuilder != builder) { 579 mBuilder = builder; 580 if (mBuilder != null) { 581 mBuilder.setStyle(this); 582 } 583 } 584 } 585 586 public Notification build() { 587 Notification notification = null; 588 if (mBuilder != null) { 589 notification = mBuilder.build(); 590 } 591 return notification; 592 } 593 } 594 595 /** 596 * Helper class for generating large-format notifications that include a large image attachment. 597 * 598 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 599 * <pre class="prettyprint"> 600 * Notification noti = new Notification.Builder() 601 * .setContentTitle("New photo from " + sender.toString()) 602 * .setContentText(subject) 603 * .setSmallIcon(R.drawable.new_post) 604 * .setLargeIcon(aBitmap) 605 * .setStyle(new Notification.BigPictureStyle() 606 * .bigPicture(aBigBitmap)) 607 * .build(); 608 * </pre> 609 * 610 * @see Notification#bigContentView 611 */ 612 public static class BigPictureStyle extends Style { 613 Bitmap mPicture; 614 615 public BigPictureStyle() { 616 } 617 618 public BigPictureStyle(Builder builder) { 619 setBuilder(builder); 620 } 621 622 /** 623 * Overrides ContentTitle in the big form of the template. 624 * This defaults to the value passed to setContentTitle(). 625 */ 626 public BigPictureStyle setBigContentTitle(CharSequence title) { 627 mBigContentTitle = title; 628 return this; 629 } 630 631 /** 632 * Set the first line of text after the detail section in the big form of the template. 633 */ 634 public BigPictureStyle setSummaryText(CharSequence cs) { 635 mSummaryText = cs; 636 mSummaryTextSet = true; 637 return this; 638 } 639 640 /** 641 * Provide the bitmap to be used as the payload for the BigPicture notification. 642 */ 643 public BigPictureStyle bigPicture(Bitmap b) { 644 mPicture = b; 645 return this; 646 } 647 } 648 649 /** 650 * Helper class for generating large-format notifications that include a lot of text. 651 * 652 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 653 * <pre class="prettyprint"> 654 * Notification noti = new Notification.Builder() 655 * .setContentTitle("New mail from " + sender.toString()) 656 * .setContentText(subject) 657 * .setSmallIcon(R.drawable.new_mail) 658 * .setLargeIcon(aBitmap) 659 * .setStyle(new Notification.BigTextStyle() 660 * .bigText(aVeryLongString)) 661 * .build(); 662 * </pre> 663 * 664 * @see Notification#bigContentView 665 */ 666 public static class BigTextStyle extends Style { 667 CharSequence mBigText; 668 669 public BigTextStyle() { 670 } 671 672 public BigTextStyle(Builder builder) { 673 setBuilder(builder); 674 } 675 676 /** 677 * Overrides ContentTitle in the big form of the template. 678 * This defaults to the value passed to setContentTitle(). 679 */ 680 public BigTextStyle setBigContentTitle(CharSequence title) { 681 mBigContentTitle = title; 682 return this; 683 } 684 685 /** 686 * Set the first line of text after the detail section in the big form of the template. 687 */ 688 public BigTextStyle setSummaryText(CharSequence cs) { 689 mSummaryText = cs; 690 mSummaryTextSet = true; 691 return this; 692 } 693 694 /** 695 * Provide the longer text to be displayed in the big form of the 696 * template in place of the content text. 697 */ 698 public BigTextStyle bigText(CharSequence cs) { 699 mBigText = cs; 700 return this; 701 } 702 } 703 704 /** 705 * Helper class for generating large-format notifications that include a list of (up to 5) strings. 706 * 707 * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so: 708 * <pre class="prettyprint"> 709 * Notification noti = new Notification.Builder() 710 * .setContentTitle("5 New mails from " + sender.toString()) 711 * .setContentText(subject) 712 * .setSmallIcon(R.drawable.new_mail) 713 * .setLargeIcon(aBitmap) 714 * .setStyle(new Notification.InboxStyle() 715 * .addLine(str1) 716 * .addLine(str2) 717 * .setContentTitle("") 718 * .setSummaryText("+3 more")) 719 * .build(); 720 * </pre> 721 * 722 * @see Notification#bigContentView 723 */ 724 public static class InboxStyle extends Style { 725 ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(); 726 727 public InboxStyle() { 728 } 729 730 public InboxStyle(Builder builder) { 731 setBuilder(builder); 732 } 733 734 /** 735 * Overrides ContentTitle in the big form of the template. 736 * This defaults to the value passed to setContentTitle(). 737 */ 738 public InboxStyle setBigContentTitle(CharSequence title) { 739 mBigContentTitle = title; 740 return this; 741 } 742 743 /** 744 * Set the first line of text after the detail section in the big form of the template. 745 */ 746 public InboxStyle setSummaryText(CharSequence cs) { 747 mSummaryText = cs; 748 mSummaryTextSet = true; 749 return this; 750 } 751 752 /** 753 * Append a line to the digest section of the Inbox notification. 754 */ 755 public InboxStyle addLine(CharSequence cs) { 756 mTexts.add(cs); 757 return this; 758 } 759 } 760 761 public static class Action { 762 public int icon; 763 public CharSequence title; 764 public PendingIntent actionIntent; 765 766 public Action(int icon_, CharSequence title_, PendingIntent intent_) { 767 this.icon = icon_; 768 this.title = title_; 769 this.actionIntent = intent_; 770 } 771 } 772} 773