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

2

17

Background

Android M presents a new way to handle selected text (link here), even from outside of your app . Text selection can be handled as such:

enter image description here

I know it's possible to handle the selected text from outside the app, because if I go to the web browser (or any other place that allows text selection), I can see that I can use the "API demos" app to handle the selected text.

The problem

I can't see a lot of information about how to do it.

The question

  1. What should be added in code (and manifest) to be able to handle the selected text from outside the app ?
  2. 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 ?
Vociferous answered 28/5, 2015 at 22:26 Comment(4)
Nothing in what you linked to describes "from outside your app".Boomkin
@Boomkin That's why I'm asking this question, because it's missing. As I've written, I know this is possible because I've ran it on the emulator, selecting text outside of the API demos. It even appeared on my own app. Choosing the "API demos" from the context menu opens the "API demos" app and it shows what I've chosen.Vociferous
@androiddeveloper The link is incorrect. You might want to update it with this: developer.android.com/about/versions/marshmallow/…Derry
@Derry They probably had a typo. anyway, thanks.Vociferous
B
16

First, to clarify the question: On an M emulator, if you highlight text, you will see the new floating action mode. If you click the overflow icon, you will see "API DEMOS" show up:

M Developer Preview Emulator

Clicking that brings up an activity from the API Demos app, showing the highlighted text:

Another M Developer Preview Emulator

Replacing the value in the field and clicking the button puts your replacement text in as a replacement for whatever you had highlighted.


WARNING: The following explanation is from inspecting the API Demos code and the M Developer Preview documentation. It is very possible that this will change before M ships for realz. YMMV, unless you use the metric system, in which case YKMV.

The activity in question, that is receiving the text, supports ACTION_PROCESS_TEXT as the Intent action. EXTRA_PROCESS_TEXT will hold some text, or EXTRA_PROCESS_TEXT_READONLY will hold it if the text is read-only. The activity will be invoked via startActivityForResult(). The result Intent can have its own EXTRA_PROCESS_TEXT value, which will be the replacement text.

So, to the specific questions:

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

See above. Note that the API Demos activity (ProcessText) has this <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>

The documentation does not discuss a MIME type. I have not run any experiments to determine if the MIME type is required, and what else we might get (text/html for stuff that has spans?).

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 ?

That wouldn't seem to be possible given the documentation. That being said, it's certainly a reasonable idea (e.g., advertise a regex, or multiple regexes, via metadata in the manifest that the text must match).

Boomkin answered 28/5, 2015 at 22:48 Comment(7)
I think the question was very clear . I wrote the information is missing and that I've noticed the functionality, but can't find how to use it because it's not there. I've re-edited it just in case. About the answer, thank you. Will now tick it as I assume you are correct.Vociferous
I've written a suggestion about this : code.google.com/p/android/issues/detail?id=174972 . Hope other people would like this.Vociferous
Mime type is required, at least what I learnt from my experiments. It worked for me with text/plain. Haven't tried other mime typesPenstemon
Question: I've noticed that on Android O we can specify the type of the text, but for some reason I've so far succeeded using phone-number only for Dial action. Can you please check it out : https://mcmap.net/q/745823/-how-to-offer-actions-of-my-app-to-other-apps-via-smart-linkify-aka-quot-smart-text-selection-quot/878126 ?Vociferous
Is it possible to assign an icon for the actions that are shown on the context menu? I've noticed that on some apps there is an icon, but for most there is none.Vociferous
@androiddeveloper: I have never seen an icon here, but I don't have many (any?) apps on my "daily driver" device that offer this feature. I'd try an android:icon on the <intent-filter> and see if that has an effect.Boomkin
@Boomkin When you select a phone number, you get "add" (from Contacts app) and "message" (from Messages app), both with icons. I think it's done by the smart text selection and not by PROCESS_TEXT, and sadly in order to show new ones, Google requires you to request it first, and they will need to accept the request. But I wonder why PROCESS_TEXT would be without any icon.Vociferous
A
1

This article on Android Developers Blog may be relevant, it describes how Google Translate option can be added to overflow text selection menu.

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);
    }
}
Ashwell answered 13/12, 2015 at 9:32 Comment(1)
hidro - do you know how the onInitializeMenu is triggered?Nidifugous

© 2022 - 2024 — McMap. All rights reserved.