|
|
@@ -1,45 +1,51 @@
|
|
|
-package com.atmob.keyboard_android
|
|
|
+package com.atmob.keyboard_android.keyboard
|
|
|
|
|
|
+import android.annotation.SuppressLint
|
|
|
import android.content.ClipboardManager
|
|
|
import android.inputmethodservice.InputMethodService
|
|
|
-import android.util.Log
|
|
|
import android.view.View
|
|
|
+import android.view.inputmethod.EditorInfo
|
|
|
import android.widget.Button
|
|
|
import android.widget.EditText
|
|
|
import android.widget.GridLayout
|
|
|
import android.widget.Toast
|
|
|
-import android.view.inputmethod.EditorInfo
|
|
|
-import io.flutter.embedding.engine.FlutterEngine
|
|
|
+import com.atmob.keyboard_android.R
|
|
|
+import com.atmob.keyboard_android.util.LogUtil
|
|
|
import io.flutter.embedding.engine.FlutterEngineCache
|
|
|
import io.flutter.plugin.common.MethodCall
|
|
|
import io.flutter.plugin.common.MethodChannel
|
|
|
-import io.flutter.plugin.common.EventChannel
|
|
|
-
|
|
|
-import com.atmob.keyboard_android.KeyboardAndroidPlugin
|
|
|
|
|
|
+/**
|
|
|
+ * 自定义键盘的输入法服务
|
|
|
+ */
|
|
|
class CustomKeyboardService : InputMethodService() {
|
|
|
+ /**
|
|
|
+ * 用于与 Flutter 端通信的 MethodChannel
|
|
|
+ */
|
|
|
+ private lateinit var mMethodChannel: MethodChannel
|
|
|
|
|
|
- private val TAG = "qqq CustomKeyboardService"
|
|
|
-
|
|
|
- private lateinit var methodChannel: MethodChannel // 用于与 Flutter 端通信的 MethodChannel
|
|
|
-
|
|
|
- private var keyboardView2: View? = null // 保存键盘视图
|
|
|
-
|
|
|
- private var keyMappings: List<Pair<String, String>> = listOf() // 存储按键映射
|
|
|
+ /**
|
|
|
+ * 保存键盘视图
|
|
|
+ */
|
|
|
+ private var vKeyboardView: View? = null
|
|
|
|
|
|
+ /**
|
|
|
+ * 存储按键映射
|
|
|
+ */
|
|
|
+ private var mKeyMappings: List<Pair<String, String>> = listOf()
|
|
|
|
|
|
override fun onCreate() {
|
|
|
super.onCreate()
|
|
|
- Log.d(TAG, "输入法服务已启动!")
|
|
|
+ LogUtil.d("输入法服务已启动!")
|
|
|
|
|
|
val flutterEngine = FlutterEngineCache.getInstance().get("my_engine_id")
|
|
|
if (flutterEngine != null) {
|
|
|
- methodChannel =
|
|
|
+ mMethodChannel =
|
|
|
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "keyboard_android")
|
|
|
- Log.d(TAG, "MethodChannel 初始化成功")
|
|
|
+ LogUtil.d("MethodChannel 初始化成功")
|
|
|
|
|
|
// 设置 MethodChannel 的回调
|
|
|
- methodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
|
|
|
+ mMethodChannel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
|
|
|
when (call.method) {
|
|
|
"inputText" -> {
|
|
|
val text = call.argument<String>("text")
|
|
|
@@ -53,18 +59,15 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
} else {
|
|
|
- Log.e(TAG, "FlutterEngine 未找到,MethodChannel 无法初始化")
|
|
|
+ LogUtil.e("FlutterEngine 未找到,MethodChannel 无法初始化")
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
override fun onCreateInputView(): View {
|
|
|
- Log.d(TAG, "onCreateInputView!")
|
|
|
+ LogUtil.d("onCreateInputView!")
|
|
|
val keyboardView = layoutInflater.inflate(R.layout.keyboard_layout, null)
|
|
|
- keyboardView2 = keyboardView
|
|
|
+ vKeyboardView = keyboardView
|
|
|
|
|
|
// 获取按键映射
|
|
|
fetchKeyMappings()
|
|
|
@@ -74,31 +77,32 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
|
|
|
override fun onStartInputView(info: EditorInfo?, restarting: Boolean) {
|
|
|
super.onStartInputView(info, restarting)
|
|
|
- Log.d(TAG, "onStartInputView: 重新加载键盘数据")
|
|
|
- fetchKeyMappings() // 重新获取按键映射
|
|
|
+ LogUtil.d("onStartInputView: 重新加载键盘数据")
|
|
|
+ // 重新获取按键映射
|
|
|
+ fetchKeyMappings()
|
|
|
}
|
|
|
|
|
|
/**通过 KeyboardAndroidPlugin 获取按键映射**/
|
|
|
private fun fetchKeyMappings() {
|
|
|
// 通过 methodChannel 获取按键映射
|
|
|
- methodChannel.invokeMethod("getKeyMappings", null, object : MethodChannel.Result {
|
|
|
+ mMethodChannel.invokeMethod("getKeyMappings", null, object : MethodChannel.Result {
|
|
|
override fun success(result: Any?) {
|
|
|
// 如果获取成功,处理键映射
|
|
|
if (result is List<*>) {
|
|
|
- keyMappings = result.filterIsInstance<Map<String, String>>().map {
|
|
|
+ mKeyMappings = result.filterIsInstance<Map<String, String>>().map {
|
|
|
it["label"]!! to it["method"]!!
|
|
|
}
|
|
|
- Log.d(TAG, "按键映射获取成功: $keyMappings")
|
|
|
- setupKeyboardButtons(keyboardView2!!)
|
|
|
+ LogUtil.d("按键映射获取成功: $mKeyMappings")
|
|
|
+ setupKeyboardButtons(vKeyboardView!!)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
|
|
- Log.e(TAG, "获取按键映射失败: $errorMessage")
|
|
|
+ LogUtil.d("获取按键映射失败: $errorMessage")
|
|
|
}
|
|
|
|
|
|
override fun notImplemented() {
|
|
|
- Log.e(TAG, "Flutter 端未实现 getKeyMappings 方法")
|
|
|
+ LogUtil.d("Flutter 端未实现 getKeyMappings 方法")
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
@@ -106,12 +110,12 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
|
|
|
/**
|
|
|
* 设置键盘按钮
|
|
|
- * @param keyboardView 键盘视图
|
|
|
- * @param keyMappings 按键映射
|
|
|
*
|
|
|
+ * @param keyboardView 键盘视图
|
|
|
*/
|
|
|
+ @SuppressLint("ClickableViewAccessibility")
|
|
|
private fun setupKeyboardButtons(keyboardView: View) {
|
|
|
- Log.d(TAG, "当前键映射: $keyMappings") // 打印映射
|
|
|
+ LogUtil.d("当前键映射: $mKeyMappings") // 打印映射
|
|
|
val editText = keyboardView.findViewById<EditText>(R.id.keyboard_input)
|
|
|
val btnPaste = keyboardView.findViewById<Button>(R.id.btn_paste)
|
|
|
val btnDelete = keyboardView.findViewById<Button>(R.id.btn_delete)
|
|
|
@@ -119,23 +123,32 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
val btnSend = keyboardView.findViewById<Button>(R.id.btn_send)
|
|
|
val numberPad = keyboardView.findViewById<GridLayout>(R.id.number_pad)
|
|
|
|
|
|
- editText.setOnTouchListener { _, _ -> true } // 禁止触摸输入
|
|
|
- numberPad.removeAllViews() // 清空,避免重复创建
|
|
|
- Log.d(TAG, "setupKeyboardButtons: 添加 ${keyMappings.size} 个按钮")
|
|
|
- keyMappings.forEach { (label, methodName) ->
|
|
|
+ // 禁止触摸输入
|
|
|
+ editText.setOnTouchListener { _, _ -> true }
|
|
|
+ // 清空,避免重复创建
|
|
|
+ numberPad.removeAllViews()
|
|
|
+
|
|
|
+ LogUtil.d("setupKeyboardButtons: 添加 ${mKeyMappings.size} 个按钮")
|
|
|
+
|
|
|
+ mKeyMappings.forEach { (label, methodName) ->
|
|
|
val button = Button(this).apply {
|
|
|
text = label
|
|
|
layoutParams = GridLayout.LayoutParams()
|
|
|
setOnClickListener {
|
|
|
-
|
|
|
- sendDynamicTextRequest(methodName, editText.text.toString()) // **每次点击时动态获取数据**
|
|
|
+ // 每次点击时动态获取数据
|
|
|
+ sendDynamicTextRequest(methodName, editText.text.toString())
|
|
|
}
|
|
|
}
|
|
|
numberPad.addView(button)
|
|
|
}
|
|
|
|
|
|
- btnPaste.setOnClickListener { pasteText(editText) }
|
|
|
- btnDelete.setOnClickListener { currentInputConnection.deleteSurroundingText(1, 0) }
|
|
|
+ btnPaste.setOnClickListener {
|
|
|
+ pasteText(editText)
|
|
|
+ }
|
|
|
+
|
|
|
+ btnDelete.setOnClickListener {
|
|
|
+ currentInputConnection.deleteSurroundingText(1, 0)
|
|
|
+ }
|
|
|
btnClear.setOnClickListener {
|
|
|
currentInputConnection.deleteSurroundingText(
|
|
|
Int.MAX_VALUE,
|
|
|
@@ -147,31 +160,33 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * **动态调用 Flutter 获取文本**
|
|
|
+ * 动态调用 Flutter 获取文本
|
|
|
+ *
|
|
|
* @param methodName 方法名
|
|
|
* @param currentContent 当前输入连接
|
|
|
*/
|
|
|
private fun sendDynamicTextRequest(methodName: String, currentContent: String) {
|
|
|
- methodChannel.invokeMethod(
|
|
|
+ mMethodChannel.invokeMethod(
|
|
|
"sendDynamicTextRequest",
|
|
|
mapOf("method" to methodName, "currentContent" to currentContent),
|
|
|
object : MethodChannel.Result {
|
|
|
override fun success(result: Any?) {
|
|
|
- Log.d(TAG, "sendDynamicTextRequest 请求已发送")
|
|
|
+ LogUtil.d("sendDynamicTextRequest 请求已发送")
|
|
|
}
|
|
|
|
|
|
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
|
|
- Log.e(TAG, "获取动态文本失败: $errorMessage")
|
|
|
+ LogUtil.d("获取动态文本失败: $errorMessage")
|
|
|
}
|
|
|
|
|
|
override fun notImplemented() {
|
|
|
- Log.e(TAG, "Flutter 端未实现 sendDynamicTextRequest 方法")
|
|
|
+ LogUtil.d("Flutter 端未实现 sendDynamicTextRequest 方法")
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- // 剪贴板粘贴
|
|
|
+ /**
|
|
|
+ * 剪贴板粘贴
|
|
|
+ */
|
|
|
private fun pasteText(editText: EditText) {
|
|
|
val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
|
|
val clipData = clipboard.primaryClip
|
|
|
@@ -182,10 +197,8 @@ class CustomKeyboardService : InputMethodService() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public fun inputText(text: String) {
|
|
|
-
|
|
|
- Log.d(TAG, "inputText: $text")
|
|
|
+ private fun inputText(text: String) {
|
|
|
+ LogUtil.d("inputText: $text")
|
|
|
currentInputConnection.commitText(text, 1)
|
|
|
}
|
|
|
-
|
|
|
}
|