am 5cadc3b0: Add RemoteInput, Grouping, and Extender to Notification api.
* commit '5cadc3b00aa775a63518383046c902b130e09b4c': Add RemoteInput, Grouping, and Extender to Notification api.
This commit is contained in:
@@ -3916,6 +3916,8 @@ package android.app {
|
||||
ctor public Notification(android.os.Parcel);
|
||||
method public android.app.Notification clone();
|
||||
method public int describeContents();
|
||||
method public java.lang.String getGroup();
|
||||
method public java.lang.String getSortKey();
|
||||
method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator CREATOR;
|
||||
@@ -3942,6 +3944,7 @@ package android.app {
|
||||
field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
|
||||
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
|
||||
field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
|
||||
field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
|
||||
field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
|
||||
field public static final int FLAG_INSISTENT = 4; // 0x4
|
||||
field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
|
||||
@@ -3985,6 +3988,7 @@ package android.app {
|
||||
method public android.app.Notification.Action clone();
|
||||
method public int describeContents();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public android.app.RemoteInput[] getRemoteInputs();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator CREATOR;
|
||||
field public android.app.PendingIntent actionIntent;
|
||||
@@ -3992,14 +3996,20 @@ package android.app {
|
||||
field public java.lang.CharSequence title;
|
||||
}
|
||||
|
||||
public static class Notification.Action.Builder {
|
||||
public static final class Notification.Action.Builder {
|
||||
ctor public Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent);
|
||||
ctor public Notification.Action.Builder(android.app.Notification.Action);
|
||||
method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
|
||||
method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
|
||||
method public android.app.Notification.Action.Builder apply(android.app.Notification.Action.Builder.Extender);
|
||||
method public android.app.Notification.Action build();
|
||||
method public android.os.Bundle getExtras();
|
||||
}
|
||||
|
||||
public static abstract interface Notification.Action.Builder.Extender {
|
||||
method public abstract android.app.Notification.Action.Builder applyTo(android.app.Notification.Action.Builder);
|
||||
}
|
||||
|
||||
public static class Notification.BigPictureStyle extends android.app.Notification.Style {
|
||||
ctor public Notification.BigPictureStyle();
|
||||
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
|
||||
@@ -4022,6 +4032,7 @@ package android.app {
|
||||
method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent);
|
||||
method public android.app.Notification.Builder addAction(android.app.Notification.Action);
|
||||
method public android.app.Notification.Builder addExtras(android.os.Bundle);
|
||||
method public android.app.Notification.Builder apply(android.app.Notification.Builder.Extender);
|
||||
method public android.app.Notification build();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public deprecated android.app.Notification getNotification();
|
||||
@@ -4035,6 +4046,8 @@ package android.app {
|
||||
method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
|
||||
method public android.app.Notification.Builder setExtras(android.os.Bundle);
|
||||
method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
|
||||
method public android.app.Notification.Builder setGroup(java.lang.String);
|
||||
method public android.app.Notification.Builder setGroupSummary(boolean);
|
||||
method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
|
||||
method public android.app.Notification.Builder setLights(int, int, int);
|
||||
method public android.app.Notification.Builder setLocalOnly(boolean);
|
||||
@@ -4046,6 +4059,7 @@ package android.app {
|
||||
method public android.app.Notification.Builder setShowWhen(boolean);
|
||||
method public android.app.Notification.Builder setSmallIcon(int);
|
||||
method public android.app.Notification.Builder setSmallIcon(int, int);
|
||||
method public android.app.Notification.Builder setSortKey(java.lang.String);
|
||||
method public android.app.Notification.Builder setSound(android.net.Uri);
|
||||
method public android.app.Notification.Builder setSound(android.net.Uri, int);
|
||||
method public android.app.Notification.Builder setStyle(android.app.Notification.Style);
|
||||
@@ -4057,6 +4071,10 @@ package android.app {
|
||||
method public android.app.Notification.Builder setWhen(long);
|
||||
}
|
||||
|
||||
public static abstract interface Notification.Builder.Extender {
|
||||
method public abstract android.app.Notification.Builder applyTo(android.app.Notification.Builder);
|
||||
}
|
||||
|
||||
public static class Notification.InboxStyle extends android.app.Notification.Style {
|
||||
ctor public Notification.InboxStyle();
|
||||
ctor public Notification.InboxStyle(android.app.Notification.Builder);
|
||||
@@ -4160,6 +4178,31 @@ package android.app {
|
||||
field public static final int STYLE_SPINNER = 0; // 0x0
|
||||
}
|
||||
|
||||
public final class RemoteInput implements android.os.Parcelable {
|
||||
method public static void addResultsToIntent(android.app.RemoteInput[], android.content.Intent, android.os.Bundle);
|
||||
method public int describeContents();
|
||||
method public boolean getAllowFreeFormInput();
|
||||
method public java.lang.CharSequence[] getChoices();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public java.lang.CharSequence getLabel();
|
||||
method public java.lang.String getResultKey();
|
||||
method public static android.os.Bundle getResultsFromIntent(android.content.Intent);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator CREATOR;
|
||||
field public static final java.lang.String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
|
||||
field public static final java.lang.String RESULTS_CLIP_LABEL = "android.remoteinput.results";
|
||||
}
|
||||
|
||||
public static final class RemoteInput.Builder {
|
||||
ctor public RemoteInput.Builder(java.lang.String);
|
||||
method public android.app.RemoteInput.Builder addExtras(android.os.Bundle);
|
||||
method public android.app.RemoteInput build();
|
||||
method public android.os.Bundle getExtras();
|
||||
method public android.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
|
||||
method public android.app.RemoteInput.Builder setChoices(java.lang.CharSequence[]);
|
||||
method public android.app.RemoteInput.Builder setLabel(java.lang.CharSequence);
|
||||
}
|
||||
|
||||
public class SearchManager implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
|
||||
method public android.content.ComponentName getGlobalSearchActivity();
|
||||
method public android.app.SearchableInfo getSearchableInfo(android.content.ComponentName);
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.android.internal.R;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* A class that represents how a persistent notification is to be presented to
|
||||
@@ -355,6 +356,14 @@ public class Notification implements Parcelable
|
||||
*/
|
||||
public static final int FLAG_LOCAL_ONLY = 0x00000100;
|
||||
|
||||
/**
|
||||
* Bit to be bitswise-ored into the {@link #flags} field that should be
|
||||
* set if this notification is the group summary for a group of notifications.
|
||||
* Grouped notifications may display in a cluster or stack on devices which
|
||||
* support such rendering. Requires a group key also be set using {@link Builder#setGroup}.
|
||||
*/
|
||||
public static final int FLAG_GROUP_SUMMARY = 0x00000200;
|
||||
|
||||
public int flags;
|
||||
|
||||
/**
|
||||
@@ -493,6 +502,34 @@ public class Notification implements Parcelable
|
||||
*/
|
||||
public String category;
|
||||
|
||||
private String mGroupKey;
|
||||
|
||||
/**
|
||||
* Get the key used to group this notification into a cluster or stack
|
||||
* with other notifications on devices which support such rendering.
|
||||
*/
|
||||
public String getGroup() {
|
||||
return mGroupKey;
|
||||
}
|
||||
|
||||
private String mSortKey;
|
||||
|
||||
/**
|
||||
* Get a sort key that orders this notification among other notifications from the
|
||||
* same package. This can be useful if an external sort was already applied and an app
|
||||
* would like to preserve this. Notifications will be sorted lexicographically using this
|
||||
* value, although providing different priorities in addition to providing sort key may
|
||||
* cause this value to be ignored.
|
||||
*
|
||||
* <p>This sort key can also be used to order members of a notification group. See
|
||||
* {@link Builder#setGroup}.
|
||||
*
|
||||
* @see String#compareTo(String)
|
||||
*/
|
||||
public String getSortKey() {
|
||||
return mSortKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional semantic data to be carried around with this Notification.
|
||||
* <p>
|
||||
@@ -659,15 +696,18 @@ public class Notification implements Parcelable
|
||||
*/
|
||||
public static class Action implements Parcelable {
|
||||
private final Bundle mExtras;
|
||||
private RemoteInput[] mRemoteInputs;
|
||||
|
||||
/**
|
||||
* Small icon representing the action.
|
||||
*/
|
||||
public int icon;
|
||||
|
||||
/**
|
||||
* Title of the action.
|
||||
*/
|
||||
public CharSequence title;
|
||||
|
||||
/**
|
||||
* Intent to send when the user invokes this action. May be null, in which case the action
|
||||
* may be rendered in a disabled presentation by the system UI.
|
||||
@@ -681,19 +721,23 @@ public class Notification implements Parcelable
|
||||
actionIntent = PendingIntent.CREATOR.createFromParcel(in);
|
||||
}
|
||||
mExtras = in.readBundle();
|
||||
mRemoteInputs = in.createTypedArray(RemoteInput.CREATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}.
|
||||
*/
|
||||
public Action(int icon, CharSequence title, PendingIntent intent) {
|
||||
this(icon, title, intent, new Bundle());
|
||||
this(icon, title, intent, new Bundle(), null);
|
||||
}
|
||||
|
||||
private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
|
||||
private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
|
||||
RemoteInput[] remoteInputs) {
|
||||
this.icon = icon;
|
||||
this.title = title;
|
||||
this.actionIntent = intent;
|
||||
this.mExtras = extras != null ? extras : new Bundle();
|
||||
this.mRemoteInputs = remoteInputs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,14 +747,23 @@ public class Notification implements Parcelable
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of inputs to be collected from the user when this action is sent.
|
||||
* May return null if no remote inputs were added.
|
||||
*/
|
||||
public RemoteInput[] getRemoteInputs() {
|
||||
return mRemoteInputs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for {@link Action} objects.
|
||||
*/
|
||||
public static class Builder {
|
||||
public static final class Builder {
|
||||
private final int mIcon;
|
||||
private final CharSequence mTitle;
|
||||
private final PendingIntent mIntent;
|
||||
private final Bundle mExtras;
|
||||
private ArrayList<RemoteInput> mRemoteInputs;
|
||||
|
||||
/**
|
||||
* Construct a new builder for {@link Action} object.
|
||||
@@ -719,7 +772,7 @@ public class Notification implements Parcelable
|
||||
* @param intent the {@link PendingIntent} to fire when users trigger this action
|
||||
*/
|
||||
public Builder(int icon, CharSequence title, PendingIntent intent) {
|
||||
this(icon, title, intent, new Bundle());
|
||||
this(icon, title, intent, new Bundle(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -728,14 +781,20 @@ public class Notification implements Parcelable
|
||||
* @param action the action to read fields from.
|
||||
*/
|
||||
public Builder(Action action) {
|
||||
this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras));
|
||||
this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras),
|
||||
action.getRemoteInputs());
|
||||
}
|
||||
|
||||
private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras) {
|
||||
private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras,
|
||||
RemoteInput[] remoteInputs) {
|
||||
mIcon = icon;
|
||||
mTitle = title;
|
||||
mIntent = intent;
|
||||
mExtras = extras;
|
||||
if (remoteInputs != null) {
|
||||
mRemoteInputs = new ArrayList<RemoteInput>(remoteInputs.length);
|
||||
Collections.addAll(mRemoteInputs, remoteInputs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -761,23 +820,63 @@ public class Notification implements Parcelable
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an input to be collected from the user when this action is sent.
|
||||
* Response values can be retrieved from the fired intent by using the
|
||||
* {@link RemoteInput#getResultsFromIntent} function.
|
||||
* @param remoteInput a {@link RemoteInput} to add to the action
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder addRemoteInput(RemoteInput remoteInput) {
|
||||
if (mRemoteInputs == null) {
|
||||
mRemoteInputs = new ArrayList<RemoteInput>();
|
||||
}
|
||||
mRemoteInputs.add(remoteInput);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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
|
||||
*/
|
||||
public Action build() {
|
||||
return new Action(mIcon, mTitle, mIntent, mExtras);
|
||||
RemoteInput[] remoteInputs = mRemoteInputs != null
|
||||
? mRemoteInputs.toArray(new RemoteInput[mRemoteInputs.size()]) : null;
|
||||
return new Action(mIcon, mTitle, mIntent, mExtras, remoteInputs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action clone() {
|
||||
return new Action(
|
||||
this.icon,
|
||||
this.title,
|
||||
this.actionIntent, // safe to alias
|
||||
new Bundle(this.mExtras));
|
||||
icon,
|
||||
title,
|
||||
actionIntent, // safe to alias
|
||||
new Bundle(mExtras),
|
||||
getRemoteInputs());
|
||||
}
|
||||
@Override
|
||||
public int describeContents() {
|
||||
@@ -794,6 +893,7 @@ public class Notification implements Parcelable
|
||||
out.writeInt(0);
|
||||
}
|
||||
out.writeBundle(mExtras);
|
||||
out.writeTypedArray(mRemoteInputs, flags);
|
||||
}
|
||||
public static final Parcelable.Creator<Action> CREATOR =
|
||||
new Parcelable.Creator<Action>() {
|
||||
@@ -906,6 +1006,10 @@ public class Notification implements Parcelable
|
||||
|
||||
category = parcel.readString();
|
||||
|
||||
mGroupKey = parcel.readString();
|
||||
|
||||
mSortKey = parcel.readString();
|
||||
|
||||
extras = parcel.readBundle(); // may be null
|
||||
|
||||
actions = parcel.createTypedArray(Action.CREATOR); // may be null
|
||||
@@ -971,6 +1075,10 @@ public class Notification implements Parcelable
|
||||
|
||||
that.category = this.category;
|
||||
|
||||
that.mGroupKey = this.mGroupKey;
|
||||
|
||||
that.mSortKey = this.mSortKey;
|
||||
|
||||
if (this.extras != null) {
|
||||
try {
|
||||
that.extras = new Bundle(this.extras);
|
||||
@@ -1108,6 +1216,10 @@ public class Notification implements Parcelable
|
||||
|
||||
parcel.writeString(category);
|
||||
|
||||
parcel.writeString(mGroupKey);
|
||||
|
||||
parcel.writeString(mSortKey);
|
||||
|
||||
parcel.writeBundle(extras); // null ok
|
||||
|
||||
parcel.writeTypedArray(actions, 0); // null ok
|
||||
@@ -1226,7 +1338,18 @@ public class Notification implements Parcelable
|
||||
sb.append(Integer.toHexString(this.defaults));
|
||||
sb.append(" flags=0x");
|
||||
sb.append(Integer.toHexString(this.flags));
|
||||
sb.append(" category="); sb.append(this.category);
|
||||
if (this.category != null) {
|
||||
sb.append(" category=");
|
||||
sb.append(this.category);
|
||||
}
|
||||
if (this.mGroupKey != null) {
|
||||
sb.append(" groupKey=");
|
||||
sb.append(this.mGroupKey);
|
||||
}
|
||||
if (this.mSortKey != null) {
|
||||
sb.append(" sortKey=");
|
||||
sb.append(this.mSortKey);
|
||||
}
|
||||
if (actions != null) {
|
||||
sb.append(" ");
|
||||
sb.append(actions.length);
|
||||
@@ -1306,6 +1429,8 @@ public class Notification implements Parcelable
|
||||
private int mProgress;
|
||||
private boolean mProgressIndeterminate;
|
||||
private String mCategory;
|
||||
private String mGroupKey;
|
||||
private String mSortKey;
|
||||
private Bundle mExtras;
|
||||
private int mPriority;
|
||||
private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS);
|
||||
@@ -1717,6 +1842,51 @@ public class Notification implements Parcelable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this notification to be part of a group of notifications sharing the same key.
|
||||
* Grouped notifications may display in a cluster or stack on devices which
|
||||
* support such rendering.
|
||||
*
|
||||
* <p>To make this notification the summary for its group, also call
|
||||
* {@link #setGroupSummary}. A sort order can be specified for group members by using
|
||||
* {@link #setSortKey}.
|
||||
* @param groupKey The group key of the group.
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder setGroup(String groupKey) {
|
||||
mGroupKey = groupKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this notification to be the group summary for a group of notifications.
|
||||
* Grouped notifications may display in a cluster or stack on devices which
|
||||
* support such rendering. Requires a group key also be set using {@link #setGroup}.
|
||||
* @param isGroupSummary Whether this notification should be a group summary.
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder setGroupSummary(boolean isGroupSummary) {
|
||||
setFlag(FLAG_GROUP_SUMMARY, isGroupSummary);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a sort key that orders this notification among other notifications from the
|
||||
* same package. This can be useful if an external sort was already applied and an app
|
||||
* would like to preserve this. Notifications will be sorted lexicographically using this
|
||||
* value, although providing different priorities in addition to providing sort key may
|
||||
* cause this value to be ignored.
|
||||
*
|
||||
* <p>This sort key can also be used to order members of a notification group. See
|
||||
* {@link Builder#setGroup}.
|
||||
*
|
||||
* @see String#compareTo(String)
|
||||
*/
|
||||
public Builder setSortKey(String sortKey) {
|
||||
mSortKey = sortKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional metadata into this notification.
|
||||
*
|
||||
@@ -1826,6 +1996,28 @@ public class Notification implements Parcelable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
@@ -2028,12 +2220,13 @@ public class Notification implements Parcelable
|
||||
n.flags |= FLAG_SHOW_LIGHTS;
|
||||
}
|
||||
n.category = mCategory;
|
||||
n.mGroupKey = mGroupKey;
|
||||
n.mSortKey = mSortKey;
|
||||
n.priority = mPriority;
|
||||
if (mActions.size() > 0) {
|
||||
n.actions = new Action[mActions.size()];
|
||||
mActions.toArray(n.actions);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
297
core/java/android/app/RemoteInput.java
Normal file
297
core/java/android/app/RemoteInput.java
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.app;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* A {@code RemoteInput} object specifies input to be collected from a user to be passed along with
|
||||
* an intent inside a {@link android.app.PendingIntent} that is sent.
|
||||
* Always use {@link RemoteInput.Builder} to create instances of this class.
|
||||
* <p class="note"> See
|
||||
* <a href="{@docRoot}wear/notifications/remote-input.html">Receiving Voice Input from
|
||||
* a Notification</a> for more information on how to use this class.
|
||||
*
|
||||
* <p>The following example adds a {@code RemoteInput} to a {@link Notification.Action},
|
||||
* sets the result key as {@code quick_reply}, and sets the label as {@code Quick reply}.
|
||||
* Users are prompted to input a response when they trigger the action. The results are sent along
|
||||
* with the intent and can be retrieved with the result key (provided to the {@link Builder}
|
||||
* constructor) from the Bundle returned by {@link #getResultsFromIntent}.
|
||||
*
|
||||
* <pre class="prettyprint">
|
||||
* public static final String KEY_QUICK_REPLY_TEXT = "quick_reply";
|
||||
* Notification.Action action = new Notification.Action.Builder(
|
||||
* R.drawable.reply, "Reply", actionIntent)
|
||||
* <b>.addRemoteInput(new RemoteInput.Builder(KEY_QUICK_REPLY_TEXT)
|
||||
* .setLabel("Quick reply").build()</b>)
|
||||
* .build();</pre>
|
||||
*
|
||||
* <p>When the {@link android.app.PendingIntent} is fired, the intent inside will contain the
|
||||
* input results if collected. To access these results, use the {@link #getResultsFromIntent}
|
||||
* function. The result values will present under the result key passed to the {@link Builder}
|
||||
* constructor.
|
||||
*
|
||||
* <pre class="prettyprint">
|
||||
* public static final String KEY_QUICK_REPLY_TEXT = "quick_reply";
|
||||
* Bundle results = RemoteInput.getResultsFromIntent(intent);
|
||||
* if (results != null) {
|
||||
* CharSequence quickReplyResult = results.getCharSequence(KEY_QUICK_REPLY_TEXT);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class RemoteInput implements Parcelable {
|
||||
/** Label used to denote the clip data type used for remote input transport */
|
||||
public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
|
||||
|
||||
/** Extra added to a clip data intent object to hold the results bundle. */
|
||||
public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
|
||||
|
||||
private final String mResultKey;
|
||||
private final CharSequence mLabel;
|
||||
private final CharSequence[] mChoices;
|
||||
private final boolean mAllowFreeFormInput;
|
||||
private final Bundle mExtras;
|
||||
|
||||
private RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
|
||||
boolean allowFreeFormInput, Bundle extras) {
|
||||
this.mResultKey = resultKey;
|
||||
this.mLabel = label;
|
||||
this.mChoices = choices;
|
||||
this.mAllowFreeFormInput = allowFreeFormInput;
|
||||
this.mExtras = extras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key that the result of this input will be set in from the Bundle returned by
|
||||
* {@link #getResultsFromIntent} when the {@link android.app.PendingIntent} is sent.
|
||||
*/
|
||||
public String getResultKey() {
|
||||
return mResultKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label to display to users when collecting this input.
|
||||
*/
|
||||
public CharSequence getLabel() {
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get possible input choices. This can be {@code null} if there are no choices to present.
|
||||
*/
|
||||
public CharSequence[] getChoices() {
|
||||
return mChoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not users can provide an arbitrary value for
|
||||
* input. If you set this to {@code false}, users must select one of the
|
||||
* choices in {@link #getChoices}. An {@link IllegalArgumentException} is thrown
|
||||
* if you set this to false and {@link #getChoices} returns {@code null} or empty.
|
||||
*/
|
||||
public boolean getAllowFreeFormInput() {
|
||||
return mAllowFreeFormInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get additional metadata carried around with this remote input.
|
||||
*/
|
||||
public Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for {@link RemoteInput} objects.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final String mResultKey;
|
||||
private CharSequence mLabel;
|
||||
private CharSequence[] mChoices;
|
||||
private boolean mAllowFreeFormInput = true;
|
||||
private Bundle mExtras = new Bundle();
|
||||
|
||||
/**
|
||||
* Create a builder object for {@link RemoteInput} objects.
|
||||
* @param resultKey the Bundle key that refers to this input when collected from the user
|
||||
*/
|
||||
public Builder(String resultKey) {
|
||||
if (resultKey == null) {
|
||||
throw new IllegalArgumentException("Result key can't be null");
|
||||
}
|
||||
mResultKey = resultKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a label to be displayed to the user when collecting this input.
|
||||
* @param label The label to show to users when they input a response.
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder setLabel(CharSequence label) {
|
||||
mLabel = Notification.safeCharSequence(label);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies choices available to the user to satisfy this input.
|
||||
* @param choices an array of pre-defined choices for users input.
|
||||
* You must provide a non-null and non-empty array if
|
||||
* you set {@link #mAllowFreeFormInput} to {@code false}.
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder setChoices(CharSequence[] choices) {
|
||||
if (choices == null) {
|
||||
mChoices = null;
|
||||
} else {
|
||||
mChoices = new CharSequence[choices.length];
|
||||
for (int i = 0; i < choices.length; i++) {
|
||||
mChoices[i] = Notification.safeCharSequence(choices[i]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the user can provide arbitrary values.
|
||||
*
|
||||
* @param allowFreeFormInput The default is {@code true}.
|
||||
* If you specify {@code false}, you must provide a non-null
|
||||
* and non-empty array to {@link #setChoices} or an
|
||||
* {@link IllegalArgumentException} is thrown.
|
||||
* @return this object for method chaining
|
||||
*/
|
||||
public Builder setAllowFreeFormInput(boolean allowFreeFormInput) {
|
||||
mAllowFreeFormInput = allowFreeFormInput;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional metadata into this builder.
|
||||
*
|
||||
* <p>Values within the Bundle will replace existing extras values in this Builder.
|
||||
*
|
||||
* @see RemoteInput#getExtras
|
||||
*/
|
||||
public Builder addExtras(Bundle extras) {
|
||||
if (extras != null) {
|
||||
mExtras.putAll(extras);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata Bundle used by this Builder.
|
||||
*
|
||||
* <p>The returned Bundle is shared with this Builder.
|
||||
*/
|
||||
public Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine all of the options that have been set and return a new {@link RemoteInput}
|
||||
* object.
|
||||
*/
|
||||
public RemoteInput build() {
|
||||
return new RemoteInput(mResultKey, mLabel, mChoices, mAllowFreeFormInput, mExtras);
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteInput(Parcel in) {
|
||||
mResultKey = in.readString();
|
||||
mLabel = in.readCharSequence();
|
||||
mChoices = in.readCharSequenceArray();
|
||||
mAllowFreeFormInput = in.readInt() != 0;
|
||||
mExtras = in.readBundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote input results bundle from an intent. The returned Bundle will
|
||||
* contain a key/value for every result key populated by remote input collector.
|
||||
* Use the {@link Bundle#getCharSequence(String)} method to retrieve a value.
|
||||
* @param intent The intent object that fired in response to an action or content intent
|
||||
* which also had one or more remote input requested.
|
||||
*/
|
||||
public static Bundle getResultsFromIntent(Intent intent) {
|
||||
ClipData clipData = intent.getClipData();
|
||||
if (clipData == null) {
|
||||
return null;
|
||||
}
|
||||
ClipDescription clipDescription = clipData.getDescription();
|
||||
if (!clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT)) {
|
||||
return null;
|
||||
}
|
||||
if (clipDescription.getLabel().equals(RESULTS_CLIP_LABEL)) {
|
||||
return clipData.getItemAt(0).getIntent().getExtras().getParcelable(EXTRA_RESULTS_DATA);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate an intent object with the results gathered from remote input. This method
|
||||
* should only be called by remote input collection services when sending results to a
|
||||
* pending intent.
|
||||
* @param remoteInputs The remote inputs for which results are being provided
|
||||
* @param intent The intent to add remote inputs to. The {@link ClipData}
|
||||
* field of the intent will be modified to contain the results.
|
||||
* @param results A bundle holding the remote input results. This bundle should
|
||||
* be populated with keys matching the result keys specified in
|
||||
* {@code remoteInputs} with values being the result per key.
|
||||
*/
|
||||
public static void addResultsToIntent(RemoteInput[] remoteInputs, Intent intent,
|
||||
Bundle results) {
|
||||
Bundle resultsBundle = new Bundle();
|
||||
for (RemoteInput remoteInput : remoteInputs) {
|
||||
Object result = results.get(remoteInput.getResultKey());
|
||||
if (result instanceof CharSequence) {
|
||||
resultsBundle.putCharSequence(remoteInput.getResultKey(), (CharSequence) result);
|
||||
}
|
||||
}
|
||||
Intent clipIntent = new Intent();
|
||||
clipIntent.putExtra(EXTRA_RESULTS_DATA, resultsBundle);
|
||||
intent.setClipData(ClipData.newIntent(RESULTS_CLIP_LABEL, clipIntent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mResultKey);
|
||||
out.writeCharSequence(mLabel);
|
||||
out.writeCharSequenceArray(mChoices);
|
||||
out.writeInt(mAllowFreeFormInput ? 1 : 0);
|
||||
out.writeBundle(mExtras);
|
||||
}
|
||||
|
||||
public static final Creator<RemoteInput> CREATOR = new Creator<RemoteInput>() {
|
||||
@Override
|
||||
public RemoteInput createFromParcel(Parcel in) {
|
||||
return new RemoteInput(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteInput[] newArray(int size) {
|
||||
return new RemoteInput[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user