From 4b1ef9e20db8dd7087e8c2543fb19df1abfd983d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8A=89=E6=B8=85=E6=8F=9A?= <2465199797@qq.com> Date: Mon, 29 Jun 2026 15:14:34 +0800 Subject: [PATCH] fix(android): sync input service state with Flutter (#15419) Signed-off-by: liuqiang <2465199797@qq.com> --- .../com/carriez/flutter_hbb/InputService.kt | 20 +++++++++++++++++++ .../com/carriez/flutter_hbb/MainActivity.kt | 11 +++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt index 3ca83fbac..6a4a21bab 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt @@ -8,6 +8,7 @@ package com.carriez.flutter_hbb import android.accessibilityservice.AccessibilityService import android.accessibilityservice.GestureDescription +import android.content.Intent import android.graphics.Path import android.os.Build import android.os.Bundle @@ -68,6 +69,16 @@ class InputService : AccessibilityService() { get() = ctx != null } + private fun notifyInputState() { + val inputState = isOpen.toString() + Handler(Looper.getMainLooper()).post { + MainActivity.flutterMethodChannel?.invokeMethod( + "on_state_changed", + mapOf("name" to "input", "value" to inputState) + ) + } + } + private val logTag = "input service" private var leftIsDown = false private var touchPath = Path() @@ -716,6 +727,7 @@ class InputService : AccessibilityService() { override fun onServiceConnected() { super.onServiceConnected() ctx = this + notifyInputState() val info = AccessibilityServiceInfo() if (Build.VERSION.SDK_INT >= 33) { info.flags = FLAG_INPUT_METHOD_EDITOR or FLAG_RETRIEVE_INTERACTIVE_WINDOWS @@ -734,8 +746,16 @@ class InputService : AccessibilityService() { override fun onDestroy() { ctx = null + // Keep this fallback even though onUnbind usually notifies first. + notifyInputState() super.onDestroy() } + override fun onUnbind(intent: Intent?): Boolean { + ctx = null + notifyInputState() + return super.onUnbind(intent) + } + override fun onInterrupt() {} } diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt index fea8e5519..5561b8814 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt @@ -200,12 +200,13 @@ class MainActivity : FlutterActivity() { "stop_input" -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { InputService.ctx?.disableSelf() + } else { + InputService.ctx = null + Companion.flutterMethodChannel?.invokeMethod( + "on_state_changed", + mapOf("name" to "input", "value" to InputService.isOpen.toString()) + ) } - InputService.ctx = null - Companion.flutterMethodChannel?.invokeMethod( - "on_state_changed", - mapOf("name" to "input", "value" to InputService.isOpen.toString()) - ) result.success(true) } "cancel_notification" -> {