2323import android .graphics .Bitmap ;
2424import android .net .Uri ;
2525import android .os .Bundle ;
26+ import android .os .IBinder ;
2627import android .os .Parcel ;
2728import android .os .Parcelable ;
2829import android .text .TextUtils ;
30+ import android .util .IntProperty ;
2931import android .view .View ;
3032import android .widget .ProgressBar ;
3133import android .widget .RemoteViews ;
@@ -185,6 +187,13 @@ public class Notification implements Parcelable
185187 */
186188 public RemoteViews contentView ;
187189
190+
191+ /**
192+ * The view that will represent this notification in the pop-up "intruder alert" dialog.
193+ * @hide
194+ */
195+ public RemoteViews intruderView ;
196+
188197 /**
189198 * The bitmap that may escape the bounds of the panel and bar.
190199 */
@@ -417,6 +426,64 @@ public class Notification implements Parcelable
417426
418427 private Bundle extras ;
419428
429+ /**
430+ * Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
431+ * @hide
432+ */
433+ private static class Action implements Parcelable {
434+ public int icon ;
435+ public CharSequence title ;
436+ public PendingIntent actionIntent ;
437+ @ SuppressWarnings ("unused" )
438+ public Action () { }
439+ private Action (Parcel in ) {
440+ icon = in .readInt ();
441+ title = TextUtils .CHAR_SEQUENCE_CREATOR .createFromParcel (in );
442+ if (in .readInt () == 1 ) {
443+ actionIntent = PendingIntent .CREATOR .createFromParcel (in );
444+ }
445+ }
446+ public Action (int icon_ , CharSequence title_ , PendingIntent intent_ ) {
447+ this .icon = icon_ ;
448+ this .title = title_ ;
449+ this .actionIntent = intent_ ;
450+ }
451+ @ Override
452+ public Action clone () {
453+ return new Action (
454+ this .icon ,
455+ this .title .toString (),
456+ this .actionIntent // safe to alias
457+ );
458+ }
459+ @ Override
460+ public int describeContents () {
461+ return 0 ;
462+ }
463+ @ Override
464+ public void writeToParcel (Parcel out , int flags ) {
465+ out .writeInt (icon );
466+ TextUtils .writeToParcel (title , out , flags );
467+ if (actionIntent != null ) {
468+ out .writeInt (1 );
469+ actionIntent .writeToParcel (out , flags );
470+ } else {
471+ out .writeInt (0 );
472+ }
473+ }
474+ public static final Parcelable .Creator <Action > CREATOR
475+ = new Parcelable .Creator <Action >() {
476+ public Action createFromParcel (Parcel in ) {
477+ return new Action (in );
478+ }
479+ public Action [] newArray (int size ) {
480+ return new Action [size ];
481+ }
482+ };
483+ }
484+
485+ private Action [] actions ;
486+
420487 /**
421488 * Constructs a Notification object with default values.
422489 * You might want to consider using {@link Builder} instead.
@@ -506,12 +573,17 @@ public Notification(Parcel parcel)
506573 }
507574
508575 priority = parcel .readInt ();
509-
576+
510577 kind = parcel .createStringArray (); // may set kind to null
511578
512579 if (parcel .readInt () != 0 ) {
513580 extras = parcel .readBundle ();
514581 }
582+
583+ actions = parcel .createTypedArray (Action .CREATOR );
584+ if (parcel .readInt () != 0 ) {
585+ intruderView = RemoteViews .CREATOR .createFromParcel (parcel );
586+ }
515587 }
516588
517589 @ Override
@@ -571,6 +643,14 @@ public Notification clone() {
571643
572644 }
573645
646+ that .actions = new Action [this .actions .length ];
647+ for (int i =0 ; i <this .actions .length ; i ++) {
648+ that .actions [i ] = this .actions [i ].clone ();
649+ }
650+ if (this .intruderView != null ) {
651+ that .intruderView = this .intruderView .clone ();
652+ }
653+
574654 return that ;
575655 }
576656
@@ -658,6 +738,15 @@ public void writeToParcel(Parcel parcel, int flags)
658738 } else {
659739 parcel .writeInt (0 );
660740 }
741+
742+ parcel .writeTypedArray (actions , 0 );
743+
744+ if (intruderView != null ) {
745+ parcel .writeInt (1 );
746+ intruderView .writeToParcel (parcel , 0 );
747+ } else {
748+ parcel .writeInt (0 );
749+ }
661750 }
662751
663752 /**
@@ -769,7 +858,14 @@ public String toString() {
769858 sb .append (this .kind [i ]);
770859 }
771860 }
772- sb .append ("])" );
861+ sb .append ("]" );
862+ if (actions != null ) {
863+ sb .append (" " );
864+ sb .append (actions .length );
865+ sb .append (" action" );
866+ if (actions .length > 1 ) sb .append ("s" );
867+ }
868+ sb .append (")" );
773869 return sb .toString ();
774870 }
775871
@@ -821,6 +917,7 @@ public static class Builder {
821917 private ArrayList <String > mKindList = new ArrayList <String >(1 );
822918 private Bundle mExtras ;
823919 private int mPriority ;
920+ private ArrayList <Action > mActions = new ArrayList <Action >(3 );
824921
825922 /**
826923 * Constructs a new Builder with the defaults:
@@ -1203,6 +1300,19 @@ public Builder setExtras(Bundle bag) {
12031300 return this ;
12041301 }
12051302
1303+ /**
1304+ * Add an action to this notification. Actions are typically displayed by
1305+ * the system as a button adjacent to the notification content.
1306+ *
1307+ * @param icon Resource ID of a drawable that represents the action.
1308+ * @param title Text describing the action.
1309+ * @param intent PendingIntent to be fired when the action is invoked.
1310+ */
1311+ public Builder addAction (int icon , CharSequence title , PendingIntent intent ) {
1312+ mActions .add (new Action (icon , title , intent ));
1313+ return this ;
1314+ }
1315+
12061316 private void setFlag (int mask , boolean value ) {
12071317 if (value ) {
12081318 mFlags |= mask ;
@@ -1284,6 +1394,44 @@ private RemoteViews makeTickerView() {
12841394 }
12851395 }
12861396
1397+ private RemoteViews makeIntruderView () {
1398+ RemoteViews intruderView = new RemoteViews (mContext .getPackageName (),
1399+ R .layout .notification_intruder_content );
1400+ if (mLargeIcon != null ) {
1401+ intruderView .setImageViewBitmap (R .id .icon , mLargeIcon );
1402+ intruderView .setViewVisibility (R .id .icon , View .VISIBLE );
1403+ } else if (mSmallIcon != 0 ) {
1404+ intruderView .setImageViewResource (R .id .icon , mSmallIcon );
1405+ intruderView .setViewVisibility (R .id .icon , View .VISIBLE );
1406+ } else {
1407+ intruderView .setViewVisibility (R .id .icon , View .GONE );
1408+ }
1409+ if (mContentTitle != null ) {
1410+ intruderView .setTextViewText (R .id .title , mContentTitle );
1411+ }
1412+ if (mContentText != null ) {
1413+ intruderView .setTextViewText (R .id .text , mContentText );
1414+ }
1415+ if (mActions .size () > 0 ) {
1416+ intruderView .setViewVisibility (R .id .actions , View .VISIBLE );
1417+ int N = mActions .size ();
1418+ if (N >3 ) N =3 ;
1419+ final int [] BUTTONS = { R .id .action0 , R .id .action1 , R .id .action2 };
1420+ for (int i =0 ; i <N ; i ++) {
1421+ final Action action = mActions .get (i );
1422+ final int buttonId = BUTTONS [i ];
1423+
1424+ intruderView .setViewVisibility (buttonId , View .VISIBLE );
1425+ intruderView .setImageViewResource (buttonId , action .icon );
1426+ intruderView .setContentDescription (buttonId , action .title );
1427+ intruderView .setOnClickPendingIntent (buttonId , action .actionIntent );
1428+ }
1429+ } else {
1430+ intruderView .setViewVisibility (R .id .actions , View .GONE );
1431+ }
1432+ return intruderView ;
1433+ }
1434+
12871435 /**
12881436 * Combine all of the options that have been set and return a new {@link Notification}
12891437 * object.
@@ -1309,6 +1457,7 @@ public Notification getNotification() {
13091457 n .ledOffMS = mLedOffMs ;
13101458 n .defaults = mDefaults ;
13111459 n .flags = mFlags ;
1460+ n .intruderView = makeIntruderView ();
13121461 if (mLedOnMs != 0 && mLedOffMs != 0 ) {
13131462 n .flags |= FLAG_SHOW_LIGHTS ;
13141463 }
@@ -1323,6 +1472,10 @@ public Notification getNotification() {
13231472 }
13241473 n .priority = mPriority ;
13251474 n .extras = mExtras != null ? new Bundle (mExtras ) : null ;
1475+ if (mActions .size () > 0 ) {
1476+ n .actions = new Action [mActions .size ()];
1477+ mActions .toArray (n .actions );
1478+ }
13261479 return n ;
13271480 }
13281481 }
0 commit comments