diff options
Diffstat (limited to 'core/java/android/app/Notification.java')
-rw-r--r-- | core/java/android/app/Notification.java | 784 |
1 files changed, 753 insertions, 31 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index dfd927f..6e23b11 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -35,6 +35,7 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.TypedValue; +import android.view.Gravity; import android.view.View; import android.widget.ProgressBar; import android.widget.RemoteViews; @@ -46,7 +47,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.List; /** * A class that represents how a persistent notification is to be presented to @@ -767,7 +770,7 @@ public class Notification implements Parcelable */ public static class Action implements Parcelable { private final Bundle mExtras; - private RemoteInput[] mRemoteInputs; + private final RemoteInput[] mRemoteInputs; /** * Small icon representing the action. @@ -910,25 +913,12 @@ public class Notification implements Parcelable * Apply an extender to this action builder. Extenders may be used to add * metadata or change options on this builder. */ - public Builder apply(Extender extender) { - extender.applyTo(this); + public Builder extend(Extender extender) { + extender.extend(this); return this; } /** - * Extender interface for use with {@link #apply}. Extenders may be used to add - * metadata or change options on this builder. - */ - public interface Extender { - /** - * Apply this extender to a notification action builder. - * @param builder the builder to be modified. - * @return the build object for chaining. - */ - public Builder applyTo(Builder builder); - } - - /** * Combine all of the options that have been set and return a new {@link Action} * object. * @return the built action @@ -975,6 +965,121 @@ public class Notification implements Parcelable return new Action[size]; } }; + + /** + * Extender interface for use with {@link Builder#extend}. Extenders may be used to add + * metadata or change options on an action builder. + */ + public interface Extender { + /** + * Apply this extender to a notification action builder. + * @param builder the builder to be modified. + * @return the build object for chaining. + */ + public Builder extend(Builder builder); + } + + /** + * Wearable extender for notification actions. To add extensions to an action, + * create a new {@link android.app.Notification.Action.WearableExtender} object using + * the {@code WearableExtender()} constructor and apply it to a + * {@link android.app.Notification.Action.Builder} using + * {@link android.app.Notification.Action.Builder#extend}. + * + * <pre class="prettyprint"> + * Notification.Action action = new Notification.Action.Builder( + * R.drawable.archive_all, "Archive all", actionIntent) + * .apply(new Notification.Action.WearableExtender() + * .setAvailableOffline(false)) + * .build(); + * </pre> + */ + public static final class WearableExtender implements Extender { + /** Notification action extra which contains wearable extensions */ + private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS"; + + private static final String KEY_FLAGS = "flags"; + + // Flags bitwise-ored to mFlags + private static final int FLAG_AVAILABLE_OFFLINE = 0x1; + + // Default value for flags integer + private static final int DEFAULT_FLAGS = FLAG_AVAILABLE_OFFLINE; + + private int mFlags = DEFAULT_FLAGS; + + /** + * Create a {@link android.app.Notification.Action.WearableExtender} with default + * options. + */ + public WearableExtender() { + } + + /** + * Create a {@link android.app.Notification.Action.WearableExtender} by reading + * wearable options present in an existing notification action. + * @param action the notification action to inspect. + */ + public WearableExtender(Action action) { + Bundle wearableBundle = action.getExtras().getBundle(EXTRA_WEARABLE_EXTENSIONS); + if (wearableBundle != null) { + mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS); + } + } + + /** + * Apply wearable extensions to a notification action that is being built. This is + * typically called by the {@link android.app.Notification.Action.Builder#extend} + * method of {@link android.app.Notification.Action.Builder}. + */ + @Override + public Action.Builder extend(Action.Builder builder) { + Bundle wearableBundle = new Bundle(); + + if (mFlags != DEFAULT_FLAGS) { + wearableBundle.putInt(KEY_FLAGS, mFlags); + } + + builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle); + return builder; + } + + @Override + public WearableExtender clone() { + WearableExtender that = new WearableExtender(); + that.mFlags = this.mFlags; + return that; + } + + /** + * Set whether this action is available when the wearable device is not connected to + * a companion device. The user can still trigger this action when the wearable device is + * offline, but a visual hint will indicate that the action may not be available. + * Defaults to true. + */ + public WearableExtender setAvailableOffline(boolean availableOffline) { + setFlag(FLAG_AVAILABLE_OFFLINE, availableOffline); + return this; + } + + /** + * Get whether this action is available when the wearable device is not connected to + * a companion device. The user can still trigger this action when the wearable device is + * offline, but a visual hint will indicate that the action may not be available. + * Defaults to true. + */ + public boolean isAvailableOffline() { + return (mFlags & FLAG_AVAILABLE_OFFLINE) != 0; + } + + private void setFlag(int mask, boolean value) { + if (value) { + mFlags |= mask; + } else { + mFlags &= ~mask; + } + } + } } /** @@ -2169,24 +2274,11 @@ public class Notification implements Parcelable * Apply an extender to this notification builder. Extenders may be used to add * metadata or change options on this builder. */ - public Builder apply(Extender extender) { - extender.applyTo(this); + public Builder extend(Extender extender) { + extender.extend(this); return this; } - /** - * Extender interface for use with {@link #apply}. Extenders may be used to add - * metadata or change options on this builder. - */ - public interface Extender { - /** - * Apply this extender to a notification builder. - * @param builder the builder to be modified. - * @return the build object for chaining. - */ - public Builder applyTo(Builder builder); - } - private void setFlag(int mask, boolean value) { if (value) { mFlags |= mask; @@ -3163,4 +3255,634 @@ public class Notification implements Parcelable return big; } } + + /** + * Extender interface for use with {@link Builder#extend}. Extenders may be used to add + * metadata or change options on a notification builder. + */ + public interface Extender { + /** + * Apply this extender to a notification builder. + * @param builder the builder to be modified. + * @return the build object for chaining. + */ + public Builder extend(Builder builder); + } + + /** + * Helper class to add wearable extensions to notifications. + * <p class="note"> See + * <a href="{@docRoot}wear/notifications/creating.html">Creating Notifications + * for Android Wear</a> for more information on how to use this class. + * <p> + * To create a notification with wearable extensions: + * <ol> + * <li>Create a {@link android.app.Notification.Builder}, setting any desired + * properties. + * <li>Create a {@link android.app.Notification.WearableExtender}. + * <li>Set wearable-specific properties using the + * {@code add} and {@code set} methods of {@link android.app.Notification.WearableExtender}. + * <li>Call {@link android.app.Notification.Builder#extend} to apply the extensions to a + * notification. + * <li>Post the notification to the notification system with the + * {@code NotificationManager.notify(...)} methods. + * </ol> + * + * <pre class="prettyprint"> + * Notification notif = new Notification.Builder(mContext) + * .setContentTitle("New mail from " + sender.toString()) + * .setContentText(subject) + * .setSmallIcon(R.drawable.new_mail) + * .extend(new Notification.WearableExtender() + * .setContentIcon(R.drawable.new_mail)) + * .build(); + * NotificationManager notificationManger = + * (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + * notificationManger.notify(0, notif);</pre> + * + * <p>Wearable extensions can be accessed on an existing notification by using the + * {@code WearableExtender(Notification)} constructor, + * and then using the {@code get} methods to access values. + * + * <pre class="prettyprint"> + * Notification.WearableExtender wearableExtender = new Notification.WearableExtender( + * notification); + * List<Notification> pages = wearableExtender.getPages(); + * </pre> + */ + public static final class WearableExtender implements Extender { + /** + * Sentinel value for an action index that is unset. + */ + public static final int UNSET_ACTION_INDEX = -1; + + /** + * Size value for use with {@link #setCustomSizePreset} to show this notification with + * default sizing. + * <p>For custom display notifications created using {@link #setDisplayIntent}, + * the default is {@link #SIZE_LARGE}. All other notifications size automatically based + * on their content. + */ + public static final int SIZE_DEFAULT = 0; + + /** + * Size value for use with {@link #setCustomSizePreset} to show this notification + * with an extra small size. + * <p>This value is only applicable for custom display notifications created using + * {@link #setDisplayIntent}. + */ + public static final int SIZE_XSMALL = 1; + + /** + * Size value for use with {@link #setCustomSizePreset} to show this notification + * with a small size. + * <p>This value is only applicable for custom display notifications created using + * {@link #setDisplayIntent}. + */ + public static final int SIZE_SMALL = 2; + + /** + * Size value for use with {@link #setCustomSizePreset} to show this notification + * with a medium size. + * <p>This value is only applicable for custom display notifications created using + * {@link #setDisplayIntent}. + */ + public static final int SIZE_MEDIUM = 3; + + /** + * Size value for use with {@link #setCustomSizePreset} to show this notification + * with a large size. + * <p>This value is only applicable for custom display notifications created using + * {@link #setDisplayIntent}. + */ + public static final int SIZE_LARGE = 4; + + /** Notification extra which contains wearable extensions */ + private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS"; + + // Keys within EXTRA_WEARABLE_OPTIONS for wearable options. + private static final String KEY_ACTIONS = "actions"; + private static final String KEY_FLAGS = "flags"; + private static final String KEY_DISPLAY_INTENT = "displayIntent"; + private static final String KEY_PAGES = "pages"; + private static final String KEY_BACKGROUND = "background"; + private static final String KEY_CONTENT_ICON = "contentIcon"; + private static final String KEY_CONTENT_ICON_GRAVITY = "contentIconGravity"; + private static final String KEY_CONTENT_ACTION_INDEX = "contentActionIndex"; + private static final String KEY_CUSTOM_SIZE_PRESET = "customSizePreset"; + private static final String KEY_CUSTOM_CONTENT_HEIGHT = "customContentHeight"; + private static final String KEY_GRAVITY = "gravity"; + + // Flags bitwise-ored to mFlags + private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1; + private static final int FLAG_HINT_HIDE_ICON = 1 << 1; + private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2; + private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3; + + // Default value for flags integer + private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE; + + private static final int DEFAULT_CONTENT_ICON_GRAVITY = Gravity.END; + private static final int DEFAULT_GRAVITY = Gravity.BOTTOM; + + private ArrayList<Action> mActions = new ArrayList<Action>(); + private int mFlags = DEFAULT_FLAGS; + private PendingIntent mDisplayIntent; + private ArrayList<Notification> mPages = new ArrayList<Notification>(); + private Bitmap mBackground; + private int mContentIcon; + private int mContentIconGravity = DEFAULT_CONTENT_ICON_GRAVITY; + private int mContentActionIndex = UNSET_ACTION_INDEX; + private int mCustomSizePreset = SIZE_DEFAULT; + private int mCustomContentHeight; + private int mGravity = DEFAULT_GRAVITY; + + /** + * Create a {@link android.app.Notification.WearableExtender} with default + * options. + */ + public WearableExtender() { + } + + public WearableExtender(Notification notif) { + Bundle wearableBundle = notif.extras.getBundle(EXTRA_WEARABLE_EXTENSIONS); + if (wearableBundle != null) { + List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS); + if (actions != null) { + mActions.addAll(actions); + } + + mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS); + mDisplayIntent = wearableBundle.getParcelable(KEY_DISPLAY_INTENT); + + Notification[] pages = getNotificationArrayFromBundle( + wearableBundle, KEY_PAGES); + if (pages != null) { + Collections.addAll(mPages, pages); + } + + mBackground = wearableBundle.getParcelable(KEY_BACKGROUND); + mContentIcon = wearableBundle.getInt(KEY_CONTENT_ICON); + mContentIconGravity = wearableBundle.getInt(KEY_CONTENT_ICON_GRAVITY, + DEFAULT_CONTENT_ICON_GRAVITY); + mContentActionIndex = wearableBundle.getInt(KEY_CONTENT_ACTION_INDEX, + UNSET_ACTION_INDEX); + mCustomSizePreset = wearableBundle.getInt(KEY_CUSTOM_SIZE_PRESET, + SIZE_DEFAULT); + mCustomContentHeight = wearableBundle.getInt(KEY_CUSTOM_CONTENT_HEIGHT); + mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY); + } + } + + /** + * Apply wearable extensions to a notification that is being built. This is typically + * called by the {@link android.app.Notification.Builder#extend} method of + * {@link android.app.Notification.Builder}. + */ + @Override + public Notification.Builder extend(Notification.Builder builder) { + Bundle wearableBundle = new Bundle(); + + if (!mActions.isEmpty()) { + wearableBundle.putParcelableArrayList(KEY_ACTIONS, mActions); + } + if (mFlags != DEFAULT_FLAGS) { + wearableBundle.putInt(KEY_FLAGS, mFlags); + } + if (mDisplayIntent != null) { + wearableBundle.putParcelable(KEY_DISPLAY_INTENT, mDisplayIntent); + } + if (!mPages.isEmpty()) { + wearableBundle.putParcelableArray(KEY_PAGES, mPages.toArray( + new Notification[mPages.size()])); + } + if (mBackground != null) { + wearableBundle.putParcelable(KEY_BACKGROUND, mBackground); + } + if (mContentIcon != 0) { + wearableBundle.putInt(KEY_CONTENT_ICON, mContentIcon); + } + if (mContentIconGravity != DEFAULT_CONTENT_ICON_GRAVITY) { + wearableBundle.putInt(KEY_CONTENT_ICON_GRAVITY, mContentIconGravity); + } + if (mContentActionIndex != UNSET_ACTION_INDEX) { + wearableBundle.putInt(KEY_CONTENT_ACTION_INDEX, + mContentActionIndex); + } + if (mCustomSizePreset != SIZE_DEFAULT) { + wearableBundle.putInt(KEY_CUSTOM_SIZE_PRESET, mCustomSizePreset); + } + if (mCustomContentHeight != 0) { + wearableBundle.putInt(KEY_CUSTOM_CONTENT_HEIGHT, mCustomContentHeight); + } + if (mGravity != DEFAULT_GRAVITY) { + wearableBundle.putInt(KEY_GRAVITY, mGravity); + } + + builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle); + return builder; + } + + @Override + public WearableExtender clone() { + WearableExtender that = new WearableExtender(); + that.mActions = new ArrayList<Action>(this.mActions); + that.mFlags = this.mFlags; + that.mDisplayIntent = this.mDisplayIntent; + that.mPages = new ArrayList<Notification>(this.mPages); + that.mBackground = this.mBackground; + that.mContentIcon = this.mContentIcon; + that.mContentIconGravity = this.mContentIconGravity; + that.mContentActionIndex = this.mContentActionIndex; + that.mCustomSizePreset = this.mCustomSizePreset; + that.mCustomContentHeight = this.mCustomContentHeight; + that.mGravity = this.mGravity; + return that; + } + + /** + * Add a wearable action to this notification. + * + * <p>When wearable actions are added using this method, the set of actions that + * show on a wearable device splits from devices that only show actions added + * using {@link android.app.Notification.Builder#addAction}. This allows for customization + * of which actions display on different devices. + * + * @param action the action to add to this notification + * @return this object for method chaining + * @see android.app.Notification.Action + */ + public WearableExtender addAction(Action action) { + mActions.add(action); + return this; + } + + /** + * Adds wearable actions to this notification. + * + * <p>When wearable actions are added using this method, the set of actions that + * show on a wearable device splits from devices that only show actions added + * using {@link android.app.Notification.Builder#addAction}. This allows for customization + * of which actions display on different devices. + * + * @param actions the actions to add to this notification + * @return this object for method chaining + * @see android.app.Notification.Action + */ + public WearableExtender addActions(List<Action> actions) { + mActions.addAll(actions); + return this; + } + + /** + * Clear all wearable actions present on this builder. + * @return this object for method chaining. + * @see #addAction + */ + public WearableExtender clearActions() { + mActions.clear(); + return this; + } + + /** + * Get the wearable actions present on this notification. + */ + public List<Action> getActions() { + return mActions; + } + + /** + * Set an intent to launch inside of an activity view when displaying + * this notification. This {@link PendingIntent} should be for an activity. + * + * @param intent the {@link PendingIntent} for an activity + * @return this object for method chaining + * @see android.app.Notification.WearableExtender#getDisplayIntent + */ + public WearableExtender setDisplayIntent(PendingIntent intent) { + mDisplayIntent = intent; + return this; + } + + /** + * Get the intent to launch inside of an activity view when displaying this + * notification. This {@code PendingIntent} should be for an activity. + */ + public PendingIntent getDisplayIntent() { + return mDisplayIntent; + } + + /** + * Add an additional page of content to display with this notification. The current + * notification forms the first page, and pages added using this function form + * subsequent pages. This field can be used to separate a notification into multiple + * sections. + * + * @param page the notification to add as another page + * @return this object for method chaining + * @see android.app.Notification.WearableExtender#getPages + */ + public WearableExtender addPage(Notification page) { + mPages.add(page); + return this; + } + + /** + * Add additional pages of content to display with this notification. The current + * notification forms the first page, and pages added using this function form + * subsequent pages. This field can be used to separate a notification into multiple + * sections. + * + * @param pages a list of notifications + * @return this object for method chaining + * @see android.app.Notification.WearableExtender#getPages + */ + public WearableExtender addPages(List<Notification> pages) { + mPages.addAll(pages); + return this; + } + + /** + * Clear all additional pages present on this builder. + * @return this object for method chaining. + * @see #addPage + */ + public WearableExtender clearPages() { + mPages.clear(); + return this; + } + + /** + * Get the array of additional pages of content for displaying this notification. The + * current notification forms the first page, and elements within this array form + * subsequent pages. This field can be used to separate a notification into multiple + * sections. + * @return the pages for this notification + */ + public List<Notification> getPages() { + return mPages; + } + + /** + * Set a background image to be displayed behind the notification content. + * Contrary to the {@link android.app.Notification.BigPictureStyle}, this background + * will work with any notification style. + * + * @param background the background bitmap + * @return this object for method chaining + * @see android.app.Notification.WearableExtender#getBackground + */ + public WearableExtender setBackground(Bitmap background) { + mBackground = background; + return this; + } + + /** + * Get a background image to be displayed behind the notification content. + * Contrary to the {@link android.app.Notification.BigPictureStyle}, this background + * will work with any notification style. + * + * @return the background image + * @see android.app.Notification.WearableExtender#setBackground + */ + public Bitmap getBackground() { + return mBackground; + } + + /** + * Set an icon that goes with the content of this notification. + */ + public WearableExtender setContentIcon(int icon) { + mContentIcon = icon; + return this; + } + + /** + * Get an icon that goes with the content of this notification. + */ + public int getContentIcon() { + return mContentIcon; + } + + /** + * Set the gravity that the content icon should have within the notification display. + * Supported values include {@link android.view.Gravity#START} and + * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}. + * @see #setContentIcon + */ + public WearableExtender setContentIconGravity(int contentIconGravity) { + mContentIconGravity = contentIconGravity; + return this; + } + + /** + * Get the gravity that the content icon should have within the notification display. + * Supported values include {@link android.view.Gravity#START} and + * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}. + * @see #getContentIcon + */ + public int getContentIconGravity() { + return mContentIconGravity; + } + + /** + * Set an action from this notification's actions to be clickable with the content of + * this notification page. This action will no longer display separately from the + * notification content. This action's icon will display with optional subtext provided + * by the action's title. + * @param actionIndex The index of the action to hoist on the current notification page. + * If wearable actions are present, this index will apply to that list, + * otherwise it will apply to the main notification's actions list. + */ + public WearableExtender setContentAction(int actionIndex) { + mContentActionIndex = actionIndex; + return this; + } + + /** + * Get the action index of an action from this notification to show as clickable with + * the content of this notification page. When the user clicks this notification page, + * this action will trigger. This action will no longer display separately from the + * notification content. The action's icon will display with optional subtext provided + * by the action's title. + * + * <p>If wearable specific actions are present, this index will apply to that list, + * otherwise it will apply to the main notification's actions list. + */ + public int getContentAction() { + return mContentActionIndex; + } + + /** + * Set the gravity that this notification should have within the available viewport space. + * Supported values include {@link android.view.Gravity#TOP}, + * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}. + * The default value is {@link android.view.Gravity#BOTTOM}. + */ + public WearableExtender setGravity(int gravity) { + mGravity = gravity; + return this; + } + + /** + * Get the gravity that this notification should have within the available viewport space. + * Supported values include {@link android.view.Gravity#TOP}, + * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}. + * The default value is {@link android.view.Gravity#BOTTOM}. + */ + public int getGravity() { + return mGravity; + } + + /** + * Set the custom size preset for the display of this notification out of the available + * presets found in {@link android.app.Notification.WearableExtender}, e.g. + * {@link #SIZE_LARGE}. + * <p>Some custom size presets are only applicable for custom display notifications created + * using {@link android.app.Notification.WearableExtender#setDisplayIntent}. Check the + * documentation for the preset in question. See also + * {@link #setCustomContentHeight} and {@link #getCustomSizePreset}. + */ + public WearableExtender setCustomSizePreset(int sizePreset) { + mCustomSizePreset = sizePreset; + return this; + } + + /** + * Get the custom size preset for the display of this notification out of the available + * presets found in {@link android.app.Notification.WearableExtender}, e.g. + * {@link #SIZE_LARGE}. + * <p>Some custom size presets are only applicable for custom display notifications created + * using {@link #setDisplayIntent}. Check the documentation for the preset in question. + * See also {@link #setCustomContentHeight} and {@link #setCustomSizePreset}. + */ + public int getCustomSizePreset() { + return mCustomSizePreset; + } + + /** + * Set the custom height in pixels for the display of this notification's content. + * <p>This option is only available for custom display notifications created + * using {@link android.app.Notification.WearableExtender#setDisplayIntent}. See also + * {@link android.app.Notification.WearableExtender#setCustomSizePreset} and + * {@link #getCustomContentHeight}. + */ + public WearableExtender setCustomContentHeight(int height) { + mCustomContentHeight = height; + return this; + } + + /** + * Get the custom height in pixels for the display of this notification's content. + * <p>This option is only available for custom display notifications created + * using {@link #setDisplayIntent}. See also {@link #setCustomSizePreset} and + * {@link #setCustomContentHeight}. + */ + public int getCustomContentHeight() { + return mCustomContentHeight; + } + + /** + * Set whether the scrolling position for the contents of this notification should start + * at the bottom of the contents instead of the top when the contents are too long to + * display within the screen. Default is false (start scroll at the top). + */ + public WearableExtender setStartScrollBottom(boolean startScrollBottom) { + setFlag(FLAG_START_SCROLL_BOTTOM, startScrollBottom); + return this; + } + + /** + * Get whether the scrolling position for the contents of this notification should start + * at the bottom of the contents instead of the top when the contents are too long to + * display within the screen. Default is false (start scroll at the top). + */ + public boolean getStartScrollBottom() { + return (mFlags & FLAG_START_SCROLL_BOTTOM) != 0; + } + + /** + * Set whether the content intent is available when the wearable device is not connected + * to a companion device. The user can still trigger this intent when the wearable device + * is offline, but a visual hint will indicate that the content intent may not be available. + * Defaults to true. + */ + public WearableExtender setContentIntentAvailableOffline( + boolean contentIntentAvailableOffline) { + setFlag(FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE, contentIntentAvailableOffline); + return this; + } + + /** + * Get whether the content intent is available when the wearable device is not connected + * to a companion device. The user can still trigger this intent when the wearable device + * is offline, but a visual hint will indicate that the content intent may not be available. + * Defaults to true. + */ + public boolean getContentIntentAvailableOffline() { + return (mFlags & FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE) != 0; + } + + /** + * Set a hint that this notification's icon should not be displayed. + * @param hintHideIcon {@code true} to hide the icon, {@code false} otherwise. + * @return this object for method chaining + */ + public WearableExtender setHintHideIcon(boolean hintHideIcon) { + setFlag(FLAG_HINT_HIDE_ICON, hintHideIcon); + return this; + } + + /** + * Get a hint that this notification's icon should not be displayed. + * @return {@code true} if this icon should not be displayed, false otherwise. + * The default value is {@code false} if this was never set. + */ + public boolean getHintHideIcon() { + return (mFlags & FLAG_HINT_HIDE_ICON) != 0; + } + + /** + * Set a visual hint that only the background image of this notification should be + * displayed, and other semantic content should be hidden. This hint is only applicable + * to sub-pages added using {@link #addPage}. + */ + public WearableExtender setHintShowBackgroundOnly(boolean hintShowBackgroundOnly) { + setFlag(FLAG_HINT_SHOW_BACKGROUND_ONLY, hintShowBackgroundOnly); + return this; + } + + /** + * Get a visual hint that only the background image of this notification should be + * displayed, and other semantic content should be hidden. This hint is only applicable + * to sub-pages added using {@link android.app.Notification.WearableExtender#addPage}. + */ + public boolean getHintShowBackgroundOnly() { + return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0; + } + + private void setFlag(int mask, boolean value) { + if (value) { + mFlags |= mask; + } else { + mFlags &= ~mask; + } + } + } + + /** + * Get an array of Notification objects from a parcelable array bundle field. + * Update the bundle to have a typed array so fetches in the future don't need + * to do an array copy. + */ + private static Notification[] getNotificationArrayFromBundle(Bundle bundle, String key) { + Parcelable[] array = bundle.getParcelableArray(key); + if (array instanceof Notification[] || array == null) { + return (Notification[]) array; + } + Notification[] typedArray = Arrays.copyOf(array, array.length, + Notification[].class); + bundle.putParcelableArray(key, typedArray); + return typedArray; + } } |