I recently came across the app Text Infinity. It offers additional actions for selected text in Android. So I asked myself how can I create an app that provides additional actions.
(source: Google Play)
Table of Contents
How it works
Since Android 6.0 a floating text selection toolbar will appear when the text is selected. By default, the common actions like cut, copy and paste are displayed. The best part is that any app can provide custom actions for the text selection toolbar.
Basically, your activity must listen to the implicit intent ACTION_PROCESS_TEXT
. For that you have to add an intent filter inside an activity in the manifest as shown below:
<activity
android:name=".UppercaseActivity"
android:label="@string/action_uppercase"
>
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
The EXTRA_PROCESS_TEXT
parameter contains the highlighted text:
val text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)
There is one more parameter EXTRA_PROCESS_TEXT_READONLY
. It can be used to check if the action was triggered from an editable field like EditText
. So you can return a modified version of text when it is not readonly.
val readonly = intent.getBooleanExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, false)
Usually my mind understands a concept better when I see the complete code. Therefore, here is a potential implementation how it could look like:
class UppercaseActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)
val readonly = intent.getBooleanExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, false)
if(!readonly && text != null){
val outgoingIntent = Intent()
outgoingIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, text.toString().toUpperCase())
setResult(Activity.RESULT_OK, outgoingIntent)
} else {
Toast.makeText(this, "Text cannot be modified", Toast.LENGTH_SHORT).show()
}
finish()
}
}
So let's have look at our example:
Further cases
Multiple actions
In case you want to deploy multiple actions with a single app, each text selection action requires a separate activity.
<activity
android:name=".UppercaseActivity"
android:label="@string/action_uppercase"
>
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name=".LowercaseActivity"
android:label="@string/action_lowercase"
>
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name=".ReverseActivity"
android:label="@string/action_reverse"
>
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Starting a service
For the intent ACTION_PROCESS_TEXT
, the Android system looks only for activities. In other words, a service cannot be directly started by this intent. However, your activity could simply start a service subsequently.
Listening to certain types of text
Maybe you have wondered whether your action can only be triggered for certain types of text such as phone numbers, links and etc. Unfortunately there is no way to do that within the Android system. In other words, your action will always appear. So you need to validate the user input before processing it.
Watch out: launchMode singleTop
If your activity is configured as launchMode=”singleTop”
, then you must also handle the text selection action within the onNewIntent()
method. (For more information about launchMode, see Tasks)
References
- Creating custom Text Selection actions with ACTION_PROCESS_TEXT by Ian Lake
- Understand Tasks and Back Stack by Android
- Intents and Intent Filters by Android
- Cover image by Estée Janssens from Unsplash
Top comments (2)
this is not working on redmi devices, custom text selection not working on redmi device. but its working fine on other devices. can you share the solution for redmi devices?
Nice article. Did you manage a way to associate an icon to the action like the app of google contacts/messages does?