最近在开发词悦(一个 mdict 词典)的时候,需要支持全局上下文菜单,查了很多资料都没有找到合适的方法,问了下 cursor,得到了初步方案,经过稍微的改动就有了这篇教程。
本文开发环境在 Linux 下。
初始化项目
1
2
| flutter create example
cd example
|
写代码
Manifest
编辑 android/app/src/main/AndroidManifest.xml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| <!-- 省略... -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- 新增的部分 -->
<!-- android:label 是上下文菜单中显示的名称 -->
<activity
android:name=".ProcessTextActivity"
android:label="example"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
|
原生 Android
创建 android/app/src/main/kotlin/com/example/example/ProcessTextActivity.kt
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| package com.example.example
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
class ProcessTextActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val text = intent?.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)?.toString() ?: ""
val intent = Intent(this, MainActivity::class.java).apply {
action = Intent.ACTION_PROCESS_TEXT
putExtra(Intent.EXTRA_PROCESS_TEXT, text)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // 如果不加这个 flag,app 在后台运行时无法把选中的文本传给 Flutter
}
startActivity(intent)
finish()
}
}
|
编辑 android/app/src/main/kotlin/com/example/example/MainActivity.kt
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| package com.example.example
import android.content.Intent
import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.example/process_text"
private var methodChannel: MethodChannel? = null
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (intent?.action == Intent.ACTION_PROCESS_TEXT) {
val text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT)?.toString() ?: ""
methodChannel?.invokeMethod("processText", text)
}
}
}
|
Flutter 部分
编辑 lib/main.dart
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
platform.setMethodCallHandler((call) async {
if (call.method == "processText") {
final text = call.arguments as String; // call.arguments 里就是选中的文本了
print(text);
}
});
runApp(const MyApp());
}
const platform = MethodChannel("com.example.example/process_text");
|
结尾
接下来怎么样就靠你的想象力了 :)