下面列出了怎么用android.app.RemoteInput的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Creates an Intent that should be called with {@code startActivityForResult} to request the
* Remote Input data.
*
* @param pm Package Manager for checking if the intent can be resolved.
* @return Intent for Remote Input or {@code null} if Remote Input is not supported.
*/
public @Nullable Intent getInputIntent(PackageManager pm) {
Bundle extras = new Bundle();
extras.putBoolean(RemoteInputConstants.EXTRA_DISALLOW_EMOJI, true);
final Intent inputIntent =
new Intent(RemoteInputIntent.ACTION_REMOTE_INPUT)
.putExtra(
RemoteInputIntent.EXTRA_REMOTE_INPUTS,
new RemoteInput[] {
new RemoteInput.Builder(Intent.EXTRA_TEXT)
.setAllowFreeFormInput(true)
.addExtras(extras)
.build()
})
.putExtra(RemoteInputIntent.EXTRA_SKIP_CONFIRMATION_UI, true);
if (pm.resolveActivity(inputIntent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
return inputIntent;
}
return null;
}
private static Object readObj(String type, Parcel in) {
switch (getBaseType(type)) {
case FORMAT_SLICE:
return Slice.CREATOR.createFromParcel(in);
case FORMAT_TEXT:
return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
case FORMAT_IMAGE:
return Icon.CREATOR.createFromParcel(in);
case FORMAT_ACTION:
return new Pair<>(
PendingIntent.CREATOR.createFromParcel(in),
Slice.CREATOR.createFromParcel(in));
case FORMAT_INT:
return in.readInt();
case FORMAT_TIMESTAMP:
return in.readLong();
case FORMAT_REMOTE_INPUT:
return RemoteInput.CREATOR.createFromParcel(in);
case FORMAT_BUNDLE:
return Bundle.CREATOR.createFromParcel(in);
}
throw new RuntimeException("Unsupported type " + type);
}
public static void send(String room, String message) throws IllegalArgumentException { // @author ManDongI
Notification.Action session = null;
for(Session i : sessions) {
if(i.room.equals(room)) {
session = i.session;
break;
}
}
if(session == null) {
throw new IllegalArgumentException("Can't find the room");
}
Intent sendIntent = new Intent();
Bundle msg = new Bundle();
for (RemoteInput inputable : session.getRemoteInputs()) msg.putCharSequence(inputable.getResultKey(), message);
RemoteInput.addResultsToIntent(session.getRemoteInputs(), sendIntent, msg);
try {
session.actionIntent.send(context, 0, sendIntent);
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
@Nullable
static String getNotificationReply(Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
// RemoteInput was added in KITKAT_WATCH.
if (intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_REPLY) != null) {
// If the notification click went through the job scheduler, we will have set
// the reply as a standard string extra.
return intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_REPLY);
}
Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
if (remoteInputResults != null) {
CharSequence reply =
remoteInputResults.getCharSequence(NotificationConstants.KEY_TEXT_REPLY);
if (reply != null) {
return reply.toString();
}
}
}
return null;
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)
.build();
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
RemoteInput remoteInput =
new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)
.build();
}
static RemoteInput[] fromCompat(RemoteInputCompatBase.RemoteInput[] srcArray) {
if (srcArray == null) {
return null;
}
RemoteInput[] result = new RemoteInput[srcArray.length];
for (int i = 0; i < srcArray.length; i++) {
RemoteInputCompatBase.RemoteInput src = srcArray[i];
result[i] = new RemoteInput.Builder(src.getResultKey())
.setLabel(src.getLabel())
.setChoices(src.getChoices())
.setAllowFreeFormInput(src.getAllowFreeFormInput())
.addExtras(src.getExtras())
.build();
}
return result;
}
/**
* Should be called in the Activity's (or Fragment's) onActivityResult() method that was invoked
* in response to the Intent returned by {@code getInputIntent}.
*/
public void onActivityResult(Intent data) {
final Bundle result = RemoteInput.getResultsFromIntent(data);
if (result != null) {
CharSequence text = result.getCharSequence(Intent.EXTRA_TEXT);
if (text != null) {
for (int i = 0, n = text.length(); i < n; ++i) {
keyboardHelper.sendChar(text.charAt(i));
}
}
}
}
/**
* Add remote input to the slice being constructed
* @param subType Optional template-specific type information
* @see SliceItem#getSubType()
*/
public Slice.Builder addRemoteInput(RemoteInput remoteInput,
@Nullable @SliceSubtype String subType,
@SliceHint List<String> hints) {
Preconditions.checkNotNull(remoteInput);
mItems.add(new SliceItem(remoteInput, SliceItem.FORMAT_REMOTE_INPUT,
subType, hints));
return this;
}
/** Intercept the PendingIntent in RemoteInput to update the notification with replied message upon success. */
private PendingIntent proxyDirectReply(final int cid, final MutableStatusBarNotification sbn, final PendingIntent on_reply,
final RemoteInput remote_input, final @Nullable CharSequence[] input_history, final @Nullable String mention_prefix) {
final Intent proxy = new Intent(mention_prefix != null ? ACTION_MENTION : ACTION_REPLY) // Separate action to avoid PendingIntent overwrite.
.setData(Uri.fromParts(SCHEME_KEY, sbn.getKey(), null))
.putExtra(EXTRA_REPLY_ACTION, on_reply).putExtra(EXTRA_RESULT_KEY, remote_input.getResultKey())
.putExtra(EXTRA_ORIGINAL_KEY, sbn.getOriginalKey()).putExtra(EXTRA_CONVERSATION_ID, cid);
if (mention_prefix != null) proxy.putExtra(EXTRA_REPLY_PREFIX, mention_prefix);
if (SDK_INT >= N && input_history != null)
proxy.putCharSequenceArrayListExtra(EXTRA_REMOTE_INPUT_HISTORY, new ArrayList<>(Arrays.asList(input_history)));
return PendingIntent.getBroadcast(mContext, 0, proxy.setPackage(mContext.getPackageName()), FLAG_UPDATE_CURRENT);
}
@Nullable
private static String getNotificationReply(Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
// RemoteInput was added in KITKAT_WATCH.
Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
if (remoteInputResults != null) {
CharSequence reply =
remoteInputResults.getCharSequence(NotificationConstants.KEY_TEXT_REPLY);
if (reply != null) {
return reply.toString();
}
}
}
return null;
}
private CharSequence getMessageText(Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
return remoteInput.getCharSequence(Compatibility.KEY_TEXT_REPLY);
}
return null;
}
static RemoteInputCompatBase.RemoteInput[] toCompat(RemoteInput[] srcArray,
RemoteInputCompatBase.RemoteInput.Factory factory) {
if (srcArray == null) {
return null;
}
RemoteInputCompatBase.RemoteInput[] result = factory.newArray(srcArray.length);
for (int i = 0; i < srcArray.length; i++) {
RemoteInput src = srcArray[i];
result[i] = factory.build(src.getResultKey(), src.getLabel(), src.getChoices(),
src.getAllowFreeFormInput(), src.getExtras());
}
return result;
}
public static void addAction(Notification.Builder b, NotificationCompatBase.Action action) {
Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
action.getIcon(), action.getTitle(), action.getActionIntent());
if (action.getRemoteInputs() != null) {
for (RemoteInput remoteInput : RemoteInputCompatApi20.fromCompat(
action.getRemoteInputs())) {
actionBuilder.addRemoteInput(remoteInput);
}
}
if (action.getExtras() != null) {
actionBuilder.addExtras(action.getExtras());
}
b.addAction(actionBuilder.build());
}
private static NotificationCompatBase.Action getActionCompatFromAction(
Notification.Action action, NotificationCompatBase.Action.Factory actionFactory,
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
RemoteInputCompatBase.RemoteInput[] remoteInputs = RemoteInputCompatApi20.toCompat(
action.getRemoteInputs(), remoteInputFactory);
return actionFactory.build(action.icon, action.title, action.actionIntent,
action.getExtras(), remoteInputs);
}
private static Notification.Action getActionFromActionCompat(
NotificationCompatBase.Action actionCompat) {
Notification.Action.Builder actionBuilder = new Notification.Action.Builder(
actionCompat.getIcon(), actionCompat.getTitle(), actionCompat.getActionIntent())
.addExtras(actionCompat.getExtras());
RemoteInputCompatBase.RemoteInput[] remoteInputCompats = actionCompat.getRemoteInputs();
if (remoteInputCompats != null) {
RemoteInput[] remoteInputs = RemoteInputCompatApi20.fromCompat(remoteInputCompats);
for (RemoteInput remoteInput : remoteInputs) {
actionBuilder.addRemoteInput(remoteInput);
}
}
return actionBuilder.build();
}
/**
* Get a list of notification compat actions by parsing actions stored within a list of
* parcelables using the {@link Bundle#getParcelableArrayList} function in the same
* manner that framework code would do so. In API20, Using Action parcelable directly
* is correct.
*/
public static NotificationCompatBase.Action[] getActionsFromParcelableArrayList(
ArrayList<Parcelable> parcelables,
NotificationCompatBase.Action.Factory actionFactory,
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
if (parcelables == null) {
return null;
}
NotificationCompatBase.Action[] actions = actionFactory.newArray(parcelables.size());
for (int i = 0; i < actions.length; i++) {
Notification.Action action = (Notification.Action) parcelables.get(i);
actions[i] = getActionCompatFromAction(action, actionFactory, remoteInputFactory);
}
return actions;
}
@Override
protected void onResume() {
super.onResume();
if (getIntent() != null) {
Bundle inputResults = RemoteInput.getResultsFromIntent(getIntent());
if (inputResults != null) {
CharSequence replyText = inputResults.getCharSequence(KEY_REPLY);
if (replyText != null) {
Toast.makeText(this, TextUtils.concat(getString(R.string.reply_was), replyText),
Toast.LENGTH_LONG).show();
}
}
}
}
@Override
public Notification buildNotification(Context context) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
Notification page2 = buildBasicNotification(context)
.extend(new Notification.WearableExtender()
.setHintShowBackgroundOnly(true)
.setBackground(BitmapFactory.decodeResource(context.getResources(),
R.drawable.example_big_picture)))
.build();
Notification page3 = buildBasicNotification(context)
.setContentTitle(context.getString(R.string.third_page))
.setContentText(null)
.extend(new Notification.WearableExtender()
.setContentAction(0 /* action A */))
.build();
SpannableStringBuilder choice2 = new SpannableStringBuilder(
"This choice is best");
choice2.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 5, 11, 0);
return buildBasicNotification(context)
.extend(new Notification.WearableExtender()
.addAction(new Notification.Action(R.mipmap.ic_launcher,
context.getString(R.string.action_a), pendingIntent))
.addAction(new Notification.Action.Builder(R.mipmap.ic_launcher,
context.getString(R.string.reply), pendingIntent)
.addRemoteInput(new RemoteInput.Builder(MainActivity.KEY_REPLY)
.setChoices(new CharSequence[] {
context.getString(R.string.choice_1),
choice2 })
.build())
.build())
.addPage(page2)
.addPage(page3))
.build();
}
/**
* @return The remote input held by this {@link #FORMAT_REMOTE_INPUT} SliceItem
*/
public RemoteInput getRemoteInput() {
return (RemoteInput) mObj;
}
/**
* @hide
*/
public void setRemoteInputs(int viewId, RemoteInput[] remoteInputs) {
mActions.add(new SetRemoteInputsAction(viewId, remoteInputs));
}
public SetRemoteInputsAction(int viewId, RemoteInput[] remoteInputs) {
this.viewId = viewId;
this.remoteInputs = remoteInputs;
}
public SetRemoteInputsAction(Parcel parcel) {
viewId = parcel.readInt();
remoteInputs = parcel.createTypedArray(RemoteInput.CREATOR);
}
@Override public void onReceive(final Context context, final Intent proxy) {
final PendingIntent reply_action = proxy.getParcelableExtra(EXTRA_REPLY_ACTION);
final String result_key = proxy.getStringExtra(EXTRA_RESULT_KEY), reply_prefix = proxy.getStringExtra(EXTRA_REPLY_PREFIX);
final Uri data = proxy.getData(); final Bundle results = RemoteInput.getResultsFromIntent(proxy);
final CharSequence input = results != null ? results.getCharSequence(result_key) : null;
if (data == null || reply_action == null || result_key == null || input == null) return; // Should never happen
final String key = data.getSchemeSpecificPart(), original_key = proxy.getStringExtra(EXTRA_ORIGINAL_KEY);
if (BuildConfig.DEBUG && "debug".equals(input.toString())) {
final Conversation conversation = mController.getConversation(proxy.getIntExtra(EXTRA_CONVERSATION_ID, 0));
if (conversation != null) showDebugNotification(conversation, "Type: " + conversation.typeToString());
mController.recastNotification(original_key != null ? original_key : key, null);
return;
}
final CharSequence text;
if (reply_prefix != null) {
text = reply_prefix + input;
results.putCharSequence(result_key, text);
RemoteInput.addResultsToIntent(new RemoteInput[]{ new RemoteInput.Builder(result_key).build() }, proxy, results);
} else text = input;
final ArrayList<CharSequence> history = SDK_INT >= N ? proxy.getCharSequenceArrayListExtra(EXTRA_REMOTE_INPUT_HISTORY) : null;
try {
final Intent input_data = addTargetPackageAndWakeUp(reply_action);
input_data.setClipData(proxy.getClipData());
reply_action.send(mContext, 0, input_data, (pendingIntent, intent, _result_code, _result_data, _result_extras) -> {
if (BuildConfig.DEBUG) Log.d(TAG, "Reply sent: " + intent.toUri(0));
if (SDK_INT >= N) {
final Bundle addition = new Bundle(); final CharSequence[] inputs;
final boolean to_current_user = Process.myUserHandle().equals(pendingIntent.getCreatorUserHandle());
if (to_current_user && context.getPackageManager().queryBroadcastReceivers(intent, 0).isEmpty()) {
inputs = new CharSequence[] { context.getString(R.string.wechat_with_no_reply_receiver) };
} else if (history != null) {
history.add(0, text);
inputs = history.toArray(new CharSequence[0]);
} else inputs = new CharSequence[] { text };
addition.putCharSequenceArray(EXTRA_REMOTE_INPUT_HISTORY, inputs);
mController.recastNotification(original_key != null ? original_key : key, addition);
}
markRead(key);
}, null);
} catch (final PendingIntent.CanceledException e) {
Log.w(TAG, "Reply action is already cancelled: " + key);
abortBroadcast();
}
}
static Bundle getResultsFromIntent(Intent intent) {
return RemoteInput.getResultsFromIntent(intent);
}
static void addResultsToIntent(RemoteInputCompatBase.RemoteInput[] remoteInputs,
Intent intent, Bundle results) {
RemoteInput.addResultsToIntent(fromCompat(remoteInputs), intent, results);
}
public static NotificationCompatBase.Action getAction(Notification notif,
int actionIndex, NotificationCompatBase.Action.Factory actionFactory,
RemoteInputCompatBase.RemoteInput.Factory remoteInputFactory) {
return getActionCompatFromAction(notif.actions[actionIndex], actionFactory, remoteInputFactory);
}