feat: use current input method to send key

This commit is contained in:
mcfans 2023-10-20 00:32:59 +08:00
parent 26e77ba2c3
commit 9a903a1ca3
2 changed files with 10 additions and 72 deletions

View File

@ -17,6 +17,8 @@ import android.util.Log
import android.widget.EditText
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.accessibilityservice.AccessibilityServiceInfo
import android.accessibilityservice.AccessibilityServiceInfo.FLAG_INPUT_METHOD_EDITOR
import androidx.annotation.RequiresApi
import java.util.*
import kotlin.math.abs
@ -65,8 +67,6 @@ class InputService : AccessibilityService() {
private var isWheelActionsPolling = false
private var isWaitingLongPress = false
private var fakeEditTextForTextStateCalculation: EditText? = null
@RequiresApi(Build.VERSION_CODES.N)
fun onMouseInput(mask: Int, _x: Int, _y: Int) {
val x = max(0, _x)
@ -264,85 +264,24 @@ class InputService : AccessibilityService() {
@RequiresApi(Build.VERSION_CODES.N)
fun onKeyEvent(data: ByteArray) {
val keyEvent = KeyEvent.parseFrom(data);
val handler = Handler(Looper.getMainLooper())
handler.post {
findFocus(AccessibilityNodeInfo.FOCUS_INPUT)?.let { node ->
val text = node.getText()
val isShowingHint = node.isShowingHintText()
var textSelectionStart = node.getTextSelectionStart()
var textSelectionEnd = node.getTextSelectionEnd()
if (text != null) {
if (textSelectionStart > text.length) {
textSelectionStart = text.length
}
if (textSelectionEnd > text.length) {
textSelectionEnd = text.length
}
if (textSelectionStart > textSelectionEnd) {
textSelectionStart = textSelectionEnd
}
}
if (keyEvent.hasSeq()) {
val seq = keyEvent.getSeq()
var newText = ""
if ((textSelectionStart == -1) || (textSelectionEnd == -1)) {
newText = seq
} else {
newText = text.let {
it.substring(0, textSelectionStart) + seq + it.substring(textSelectionStart)
}
}
val arguments = Bundle()
arguments.putCharSequence(
AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
newText
)
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
} else {
KeyEventConverter.toAndroidKeyEvent(keyEvent).let { event ->
Log.d(logTag, "event $event text $text start $textSelectionStart end $textSelectionEnd")
if (isShowingHint) {
this.fakeEditTextForTextStateCalculation?.setText(null)
} else {
this.fakeEditTextForTextStateCalculation?.setText(text)
}
if (textSelectionStart != -1 && textSelectionEnd != -1) {
this.fakeEditTextForTextStateCalculation?.setSelection(
textSelectionStart,
textSelectionEnd
)
}
this.fakeEditTextForTextStateCalculation?.dispatchKeyEvent(event)
this.fakeEditTextForTextStateCalculation?.getText()?.let { newText ->
val arguments = Bundle()
arguments.putCharSequence(
AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
newText.toString()
)
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
}
}
getInputMethod()?.let { inputMethod ->
inputMethod.getCurrentInputConnection()?.let { inputConnection ->
KeyEventConverter.toAndroidKeyEvent(keyEvent).let { event ->
inputConnection.sendKeyEvent(event)
}
}
}
}
override fun onAccessibilityEvent(event: AccessibilityEvent) {
}
override fun onAccessibilityEvent(event: AccessibilityEvent) {}
override fun onServiceConnected() {
super.onServiceConnected()
ctx = this
fakeEditTextForTextStateCalculation = EditText(this)
val info = AccessibilityServiceInfo()
info.flags = FLAG_INPUT_METHOD_EDITOR
setServiceInfo(info)
Log.d(logTag, "onServiceConnected!")
}

View File

@ -1,6 +1,5 @@
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowsChanged"
android:canRetrieveWindowContent="true"
android:accessibilityFlags="flagDefault"
android:notificationTimeout="50"
android:description="@string/accessibility_service_description"