fix: use enhanced accessibilty node find method

This commit is contained in:
mcfans 2023-10-27 13:18:35 +08:00
parent 07bdf02af4
commit 67b2a433a8

View File

@ -268,7 +268,6 @@ class InputService : AccessibilityService() {
@RequiresApi(Build.VERSION_CODES.N) @RequiresApi(Build.VERSION_CODES.N)
fun onKeyEvent(data: ByteArray) { fun onKeyEvent(data: ByteArray) {
val keyEvent = KeyEvent.parseFrom(data) val keyEvent = KeyEvent.parseFrom(data)
val down = keyEvent.getDown()
val keyboardMode = keyEvent.getMode() val keyboardMode = keyEvent.getMode()
var textToCommit: String? = null var textToCommit: String? = null
@ -306,12 +305,119 @@ class InputService : AccessibilityService() {
} else { } else {
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())
handler.post { handler.post {
findFocus(AccessibilityNodeInfo.FOCUS_INPUT)?.let { node -> KeyEventConverter.toAndroidKeyEvent(keyEvent)?.let { event ->
val text = node.getText() val possibleNodes = possibleAccessibiltyNodes()
val isShowingHint = node.isShowingHintText() for (item in possibleNodes) {
val success = trySendKeyEvent(event, item, textToCommit)
if (success) {
break
}
}
}
}
}
}
var textSelectionStart = node.getTextSelectionStart() private fun insertAccessibilityNode(list: LinkedList<AccessibilityNodeInfo>, node: AccessibilityNodeInfo) {
var textSelectionEnd = node.getTextSelectionEnd() if (list.contains(node)) {
return
}
list.add(node)
}
private fun findChildNode(node: AccessibilityNodeInfo?): AccessibilityNodeInfo? {
if (node == null) {
return null
}
if (node.isEditable() && node.isFocusable()) {
return node
}
val childCount = node.getChildCount()
for (i in 0 until childCount) {
val child = node.getChild(i)
if (child != null) {
if (child.isEditable() && child.isFocusable()) {
return child
}
if (Build.VERSION.SDK_INT < 33) {
child.recycle()
}
}
}
for (i in 0 until childCount) {
val child = node.getChild(i)
if (child != null) {
val result = findChildNode(child)
if (Build.VERSION.SDK_INT < 33) {
if (child != result) {
child.recycle()
}
}
if (result != null) {
return result
}
}
}
return null
}
private fun possibleAccessibiltyNodes(): LinkedList<AccessibilityNodeInfo> {
val linkedList = LinkedList<AccessibilityNodeInfo>()
val latestList = LinkedList<AccessibilityNodeInfo>()
val focusInput = findFocus(AccessibilityNodeInfo.FOCUS_INPUT)
var focusAccessibilityInput = findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY)
val rootInActiveWindow = getRootInActiveWindow()
if (focusInput != null) {
if (focusInput.isFocusable() && focusInput.isEditable()) {
insertAccessibilityNode(linkedList, focusInput)
} else {
insertAccessibilityNode(latestList, focusInput)
}
}
if (focusAccessibilityInput != null) {
if (focusAccessibilityInput.isFocusable() && focusAccessibilityInput.isEditable()) {
insertAccessibilityNode(linkedList, focusAccessibilityInput)
} else {
insertAccessibilityNode(latestList, focusAccessibilityInput)
}
}
val childFromFocusInput = findChildNode(focusInput)
if (childFromFocusInput != null) {
insertAccessibilityNode(linkedList, childFromFocusInput)
}
val childFromFocusAccessibilityInput = findChildNode(focusAccessibilityInput)
if (childFromFocusAccessibilityInput != null) {
insertAccessibilityNode(linkedList, childFromFocusAccessibilityInput)
}
if (rootInActiveWindow != null) {
insertAccessibilityNode(linkedList, rootInActiveWindow)
}
for (item in latestList) {
insertAccessibilityNode(linkedList, item)
}
return linkedList
}
private fun trySendKeyEvent(event: android.view.KeyEvent, node: AccessibilityNodeInfo, textToCommit: String?): Boolean {
node.refresh()
val text = node.getText()
var isShowingHint = false
if (Build.VERSION.SDK_INT >= 26) {
isShowingHint = node.isShowingHintText()
}
var textSelectionStart = node.textSelectionStart
var textSelectionEnd = node.textSelectionEnd
if (text != null) { if (text != null) {
if (textSelectionStart > text.length) { if (textSelectionStart > text.length) {
@ -325,6 +431,8 @@ class InputService : AccessibilityService() {
} }
} }
var success = false
if (textToCommit != null) { if (textToCommit != null) {
var newText = "" var newText = ""
@ -342,9 +450,8 @@ class InputService : AccessibilityService() {
AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
newText newText
) )
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments) success = node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
} else { } else {
KeyEventConverter.toAndroidKeyEvent(keyEvent).let { event ->
if (isShowingHint) { if (isShowingHint) {
this.fakeEditTextForTextStateCalculation?.setText(null) this.fakeEditTextForTextStateCalculation?.setText(null)
} else { } else {
@ -364,13 +471,10 @@ class InputService : AccessibilityService() {
AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
newText.toString() newText.toString()
) )
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments) success = node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
}
}
}
}
} }
} }
return success
} }
@ -381,7 +485,9 @@ class InputService : AccessibilityService() {
super.onServiceConnected() super.onServiceConnected()
ctx = this ctx = this
val info = AccessibilityServiceInfo() val info = AccessibilityServiceInfo()
if (Build.VERSION.SDK_INT >= 33) {
info.flags = FLAG_INPUT_METHOD_EDITOR info.flags = FLAG_INPUT_METHOD_EDITOR
}
setServiceInfo(info) setServiceInfo(info)
fakeEditTextForTextStateCalculation = EditText(this) fakeEditTextForTextStateCalculation = EditText(this)
Log.d(logTag, "onServiceConnected!") Log.d(logTag, "onServiceConnected!")