diff --git a/app/src/main/java/li/songe/gkd/data/AttrInfo.kt b/app/src/main/java/li/songe/gkd/data/AttrInfo.kt index 1fe701f..d357f6b 100644 --- a/app/src/main/java/li/songe/gkd/data/AttrInfo.kt +++ b/app/src/main/java/li/songe/gkd/data/AttrInfo.kt @@ -15,6 +15,7 @@ data class AttrInfo( val focusable: Boolean, val checkable: Boolean, val checked: Boolean, + val longClickable: Boolean, val visibleToUser: Boolean, val left: Int, @@ -51,6 +52,7 @@ data class AttrInfo( focusable = node.isFocusable, checkable = node.isCheckable, checked = node.isChecked, + longClickable = node.isLongClickable, visibleToUser = node.isVisibleToUser, left = rect.left, diff --git a/app/src/main/java/li/songe/gkd/data/Rule.kt b/app/src/main/java/li/songe/gkd/data/Rule.kt index 6d250bd..571fd29 100644 --- a/app/src/main/java/li/songe/gkd/data/Rule.kt +++ b/app/src/main/java/li/songe/gkd/data/Rule.kt @@ -134,10 +134,6 @@ data class ActionResult( val result: Boolean, ) -val click: ActionFc = { context, node -> - if (node.isClickable) clickNode(context, node) else clickCenter(context, node) -} - val clickNode: ActionFc = { _, node -> ActionResult( action = "clickNode", result = node.performAction(AccessibilityNodeInfo.ACTION_CLICK) @@ -166,7 +162,49 @@ val clickCenter: ActionFc = { context, node -> false } ) +} +val click: ActionFc = { context, node -> + if (node.isClickable) clickNode(context, node) else clickCenter(context, node) +} + +val longClickNode: ActionFc = { _, node -> + ActionResult( + action = "longClickNode", + result = node.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK) + ) +} + +val longClickCenter: ActionFc = { context, node -> + val react = Rect() + node.getBoundsInScreen(react) + val x = (react.right + react.left) / 2f + val y = (react.bottom + react.top) / 2f + // 内部的 DEFAULT_LONG_PRESS_TIMEOUT 常量是 400 + // 而 ViewConfiguration.getLongPressTimeout() 返回 300, 这将导致触发普通的 click 事件 + ActionResult( + action = "longClickCenter", + result = if (0 <= x && 0 <= y && x <= ScreenUtils.getScreenWidth() && y <= ScreenUtils.getScreenHeight()) { + val gestureDescription = GestureDescription.Builder() + val path = Path() + path.moveTo(x, y) + gestureDescription.addStroke( + GestureDescription.StrokeDescription( + path, 0, 400L + ) + ) + // TODO 传入处理 callback + context.dispatchGesture(gestureDescription.build(), null, null) + true + } else { + false + } + ) +} + + +val longClick: ActionFc = { context, node -> + if (node.isLongClickable) longClickNode(context, node) else longClickCenter(context, node) } val backFc: ActionFc = { context, _ -> @@ -181,6 +219,9 @@ fun getActionFc(action: String?): ActionFc { "clickNode" -> clickNode "clickCenter" -> clickCenter "back" -> backFc + "longClick" -> longClick + "longClickNode" -> longClickNode + "longClickCenter" -> longClickCenter else -> click } } \ No newline at end of file diff --git a/app/src/main/java/li/songe/gkd/service/AbExt.kt b/app/src/main/java/li/songe/gkd/service/AbExt.kt index e0943e4..5a57aa2 100644 --- a/app/src/main/java/li/songe/gkd/service/AbExt.kt +++ b/app/src/main/java/li/songe/gkd/service/AbExt.kt @@ -123,6 +123,7 @@ private val getAttr: (AccessibilityNodeInfo, String) -> Any? = { node, name -> "checkable" -> node.isCheckable "checked" -> node.isChecked "focusable" -> node.isFocusable + "longClickable" -> node.isLongClickable "visibleToUser" -> node.isVisibleToUser "left" -> node.getTempRect().left