Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 62b98c7

Browse files
committed
Add tests and more documentation
1 parent 92e21b0 commit 62b98c7

File tree

3 files changed

+307
-69
lines changed

3 files changed

+307
-69
lines changed

shell/platform/android/io/flutter/embedding/engine/systemchannels/ProcessTextChannel.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
*
2121
* <p>When there is new a text context menu to display, the framework will send to the embedding the
2222
* message {@code ProcessText.queryTextActions}. In response, the {@link
23-
* io.flutter.plugin.text.ProcessTextPlugin} will return a map of all activities that can be performed
24-
* to process text. The map keys are generated IDs and the values are the activities labels.
25-
* On the first request, the {@link io.flutter.plugin.text.ProcessTextPlugin} will make a call to
26-
* Android's package manager to query all activities that can be performed for the
27-
* {@code Intent.ACTION_PROCESS_TEXT} intent.
23+
* io.flutter.plugin.text.ProcessTextPlugin} will return a map of all activities that can be
24+
* performed to process text. The map keys are generated IDs and the values are the activities
25+
* labels. On the first request, the {@link io.flutter.plugin.text.ProcessTextPlugin} will make a
26+
* call to Android's package manager to query all activities that can be performed for the {@code
27+
* Intent.ACTION_PROCESS_TEXT} intent.
2828
*
29-
* <p>When an text processing action has to be executed, the framework will send to the embedding the
30-
* message {@code ProcessText.processTextAction} with the {@code int id} of the choosen text action and the
31-
* {@code String} of text to process as arguments. In response, the {@link
29+
* <p>When an text processing action has to be executed, the framework will send to the embedding
30+
* the message {@code ProcessText.processTextAction} with the {@code int id} of the choosen text
31+
* action and the {@code String} of text to process as arguments. In response, the {@link
3232
* io.flutter.plugin.text.ProcessTextPlugin} will make a call to the Android application activity to
3333
* start the activity exposing the text action and it will return the processed text, or null if the
3434
* activity did not return a value.
@@ -107,7 +107,12 @@ public interface ProcessTextMethodHandler {
107107
/**
108108
* Requests to run a text action on a given input text.
109109
*
110-
* <p>TODO(bleroux): add documentation for parameters.
110+
* @param id The ID of the text action returned by queryTextActions.
111+
* @param input The text to be processed.
112+
* @param readOnly Indicates to the activity if the processed text will be used as read-only.
113+
* see
114+
* https://developer.android.com/reference/android/content/Intent#EXTRA_PROCESS_TEXT_READONLY
115+
* @param result The method channel result instance used to reply.
111116
*/
112117
void processTextAction(
113118
@NonNull int id,

shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55
package io.flutter.plugin.text;
66

7+
import android.annotation.TargetApi;
78
import android.app.Activity;
89
import android.content.Intent;
910
import android.content.pm.PackageManager;
1011
import android.content.pm.ResolveInfo;
1112
import android.os.Build;
1213
import androidx.annotation.NonNull;
1314
import androidx.annotation.Nullable;
15+
import androidx.annotation.RequiresApi;
1416
import io.flutter.embedding.engine.plugins.FlutterPlugin;
1517
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
1618
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
@@ -21,7 +23,11 @@
2123
import java.util.List;
2224
import java.util.Map;
2325

24-
public class ProcessTextPlugin implements FlutterPlugin, ActivityAware, ActivityResultListener {
26+
public class ProcessTextPlugin
27+
implements FlutterPlugin,
28+
ActivityAware,
29+
ActivityResultListener,
30+
ProcessTextChannel.ProcessTextMethodHandler {
2531
private static final String TAG = "ProcessTextPlugin";
2632

2733
@NonNull private final ProcessTextChannel processTextChannel;
@@ -37,65 +43,63 @@ public ProcessTextPlugin(@NonNull ProcessTextChannel processTextChannel) {
3743
this.processTextChannel = processTextChannel;
3844
this.packageManager = processTextChannel.packageManager;
3945

40-
processTextChannel.setMethodHandler(
41-
new ProcessTextChannel.ProcessTextMethodHandler() {
42-
@Override
43-
public Map<Integer, String> queryTextActions() {
44-
if (resolveInfosById == null) {
45-
resolveInfosById = new HashMap<Integer, ResolveInfo>();
46-
cacheResolveInfos();
47-
}
48-
Map<Integer, String> result = new HashMap<Integer, String>();
49-
for (Integer id : resolveInfosById.keySet()) {
50-
final ResolveInfo info = resolveInfosById.get(id);
51-
result.put(id, info.loadLabel(packageManager).toString());
52-
}
53-
return result;
54-
}
55-
56-
@Override
57-
public void processTextAction(
58-
@NonNull int id,
59-
@NonNull String text,
60-
@NonNull boolean readOnly,
61-
@NonNull MethodChannel.Result result) {
62-
if (activityBinding == null) {
63-
result.error("error", "Plugin not bound to an Activity", null);
64-
return;
65-
}
66-
67-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
68-
result.error("error", "Android version not supported", null);
69-
return;
70-
}
71-
72-
if (resolveInfosById == null) {
73-
result.error("error", "Can not process text actions before calling queryTextActions", null);
74-
return;
75-
}
76-
77-
final ResolveInfo info = resolveInfosById.get(id);
78-
if (info == null) {
79-
result.error("error", "Text processing activity not found", null);
80-
return;
81-
}
82-
83-
Integer requestCode = result.hashCode();
84-
requestsByCode.put(requestCode, result);
85-
86-
Intent intent =
87-
new Intent()
88-
.setClassName(info.activityInfo.packageName, info.activityInfo.name)
89-
.setAction(Intent.ACTION_PROCESS_TEXT)
90-
.setType("text/plain")
91-
.putExtra(Intent.EXTRA_PROCESS_TEXT, text)
92-
.putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, readOnly);
93-
94-
// Start the text processing activity. onActivityResult callback is called
95-
// when the activity completes.
96-
activityBinding.getActivity().startActivityForResult(intent, requestCode);
97-
}
98-
});
46+
processTextChannel.setMethodHandler(this);
47+
}
48+
49+
@Override
50+
public Map<Integer, String> queryTextActions() {
51+
if (resolveInfosById == null) {
52+
resolveInfosById = new HashMap<Integer, ResolveInfo>();
53+
cacheResolveInfos();
54+
}
55+
Map<Integer, String> result = new HashMap<Integer, String>();
56+
for (Integer id : resolveInfosById.keySet()) {
57+
final ResolveInfo info = resolveInfosById.get(id);
58+
result.put(id, info.loadLabel(packageManager).toString());
59+
}
60+
return result;
61+
}
62+
63+
@Override
64+
public void processTextAction(
65+
@NonNull int id,
66+
@NonNull String text,
67+
@NonNull boolean readOnly,
68+
@NonNull MethodChannel.Result result) {
69+
if (activityBinding == null) {
70+
result.error("error", "Plugin not bound to an Activity", null);
71+
return;
72+
}
73+
74+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
75+
result.error("error", "Android version not supported", null);
76+
return;
77+
}
78+
79+
if (resolveInfosById == null) {
80+
result.error("error", "Can not process text actions before calling queryTextActions", null);
81+
return;
82+
}
83+
84+
final ResolveInfo info = resolveInfosById.get(id);
85+
if (info == null) {
86+
result.error("error", "Text processing activity not found", null);
87+
return;
88+
}
89+
90+
Integer requestCode = result.hashCode();
91+
requestsByCode.put(requestCode, result);
92+
93+
Intent intent = new Intent();
94+
intent.setClassName(info.activityInfo.packageName, info.activityInfo.name);
95+
intent.setAction(Intent.ACTION_PROCESS_TEXT);
96+
intent.setType("text/plain");
97+
intent.putExtra(Intent.EXTRA_PROCESS_TEXT, text);
98+
intent.putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, readOnly);
99+
100+
// Start the text processing activity. onActivityResult callback is called
101+
// when the activity completes.
102+
activityBinding.getActivity().startActivityForResult(intent, requestCode);
99103
}
100104

101105
private void cacheResolveInfos() {
@@ -126,6 +130,8 @@ private void cacheResolveInfos() {
126130
*
127131
* <p>The result is null when an activity does not return an updated text.
128132
*/
133+
@TargetApi(Build.VERSION_CODES.M)
134+
@RequiresApi(Build.VERSION_CODES.M)
129135
public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
130136
String result = null;
131137
if (resultCode == Activity.RESULT_OK) {

0 commit comments

Comments
 (0)