如何使用从您的应用程序外部提供的 "Text Selection" 的新 Android M 功能?

How to use the new Android M feature of "Text Selection" to be offered from outside of your app?

背景

Android M 提供了一种处理选定文本的新方法 (link here),即使是在您的应用之外。文本选择可以这样处理:

我知道可以从应用程序外部处理选定的文本,因为如果我转到网络浏览器(或任何其他允许文本选择的地方),我可以看到我可以使用 "API demos" 应用来处理选定的文本。

问题

我看不到很多关于如何操作的信息。

问题

  1. 应该在代码(和清单)中添加什么才能从应用程序外部处理选定的文本?
  2. 是否可以将选择限制为某些类型的文本?例如,仅当文本类型是有效的 phone 数字时才显示应用程序?

首先,澄清一下问题:在M模拟器上,如果你突出显示文本,你会看到新的浮动动作模式。如果单击溢出图标,您将看到 "API DEMOS" 显示:

单击它会从 API 演示应用程序中调出一个 activity,显示突出显示的文本:

替换字段中的值并单击按钮将替换文本放入,以替换您突出显示的内容。


警告:以下解释来自检查 API 演示代码和 M Developer Preview 文档。这很有可能会在 M 为 realz 发货之前改变。 YMMV,除非您使用公制,在这种情况下为 YKMV。

有问题的 activity 正在接收文本,支持 ACTION_PROCESS_TEXT 作为 Intent 操作。 EXTRA_PROCESS_TEXT 将保存一些文本,或者如果文本是只读的,则 EXTRA_PROCESS_TEXT_READONLY 将保存它。 activity 将通过 startActivityForResult() 调用。结果 Intent 可以有自己的 EXTRA_PROCESS_TEXT 值,这将是替换文本。

所以,针对具体问题:

What should be added in code (and manifest) to be able to handle the selected text from outside the app ?

见上文。请注意 API 演示 activity (ProcessText) 有此 <intent-filter>:

        <intent-filter >
            <action android:name="android.intent.action.PROCESS_TEXT"/>
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>

文档不讨论 MIME 类型。我没有 运行 任何实验来确定是否需要 MIME 类型,以及我们可能会得到什么(text/html 对于有跨度的东西?)。

Is it possible to limit the selection to certain types of texts ? For example, offer to show the app only if the text type is a valid phone number ?

鉴于文档,这似乎是不可能的。话虽如此,这当然是一个合理的想法(例如,通过文本必须匹配的清单中的元数据来宣传一个正则表达式或多个正则表达式)。

This article Android 开发者博客可能相关,它描述了如何将 Google 翻译选项添加到溢出文本选择菜单。

Android apps that use Android text selection behavior will already have this feature enabled, so no extra steps need to be taken. Developers who created custom text selection behavior for their apps can easily implement this feature by following the below steps:

Scan via the PackageManager through all packages that have the PROCESS_TEXT intent filter (for example: com.google.android.apps.translate - if it installed) and add them as MenuItems into TextView selections for your app

To query the package manager, first build an intent with the action Intent.ACTION_PROCESS_TEXT, then retrieve the supported activities and add an item for each retrieved activity and attach an intent to it to launch the action

public void onInitializeMenu(Menu menu) {
    // Start with a menu Item order value that is high enough
    // so that your "PROCESS_TEXT" menu items appear after the
    // standard selection menu items like Cut, Copy, Paste.
    int menuItemOrder = 100;
    for (ResolveInfo resolveInfo : getSupportedActivities()) {
        menu.add(Menu.NONE, Menu.NONE,
                menuItemOrder++,
                getLabel(resolveInfo))
            .setIntent(createProcessTextIntentForResolveInfo(resolveInfo))
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    }
}