How to add custom item on Global long press Contex

2020-06-28 01:12发布

问题:

I want to know how google translate and wikipedia app did to add their item on the webview long press context menu. P.S. This screenshot is from Nexus 5 6.0.1 version.

回答1:

They added an activity that supports ACTION_PROCESS_TEXT via an <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>

On the Intent delivered to the activity (obtained via getIntent()), EXTRA_PROCESS_TEXT will hold some text, or EXTRA_PROCESS_TEXT_READONLY will hold it if the text is read-only. The text will be what was highlighted when the user chose the menu option that started this activity.

The activity will be invoked via startActivityForResult(). The result Intent can have its own EXTRA_PROCESS_TEXT value, which will be the replacement text.



回答2:

A complete example:

AndroidManifest.xml - code specific to activity:

<activity
    android:name=".Activity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </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>
</activity>

In Activity.java - code specific to onResume():

@Override
protected void onResume() {
    super.onResume();


    // Get Intent
    Intent intent = getIntent();
    // Clear the intent to prevent again receiving on resuming Main
    setIntent(new Intent());

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M &&
            intent.getAction().equals(Intent.ACTION_PROCESS_TEXT) &&
            intent.hasExtra(Intent.EXTRA_PROCESS_TEXT)) {
        // Text received for processing in readonly - i.e. from non-editable EditText
        boolean textToProcessIsReadonly = intent.getBooleanExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, false);
        // Text received for processing
        CharSequence textToProcess = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT);
    }
}

In Activity.java - code to send back the processed text:

private void sendProcessedText() {
    Intent intent = new Intent();
    intent.putExtra(Intent.EXTRA_PROCESS_TEXT, textProcessed);
    setResult(RESULT_OK, intent);
    super.finish();
}