You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin调试遇AVC权限拒绝+rootInActiveWindow返回Null问题求助

Android Kotlin应用:鼠标位置读取与模拟点击问题解决

问题描述

  1. 调试时持续出现AVC权限拒绝日志:
type=1400 audit(0.0:227): avc: denied { read } for name="value" dev="sysfs" ino=65762 scontext=u:r:untrusted_app:s0:c163,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.minimis.customlauncher 2023-10-18 10:03:09.470 5482-5482 .customlauncher com.minimis.customlauncher
type=1400 audit(0.0:228): avc: denied { open } for path="/sys/devices/platform/soc/500000.pinctrl/gpiochip0/gpio/gpio1209/value" dev="sysfs" ino=65762 scontext=u:r:untrusted_app:s0:c163,c256,c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.minimis.******
  1. rootInActiveWindow始终返回null,无法执行点击逻辑。

问题代码

private val nodeInfo = rootInActiveWindow;

private fun click() {
Log.d(TAG, "Before Click  [${cursorLayout.x}, ${cursorLayout.y}]")
if (nodeInfo == null) {
Log.d(TAG, "Error")
return
}else{
Log.d(TAG, "After Click..>$nodeInfo  [${cursorLayout.x}, ${cursorLayout.y}]")
}
val nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, cursorLayout.x, cursorLayout.y + 50)
if (nearestNodeToMouse != null) {
logNodeHierarchy(nearestNodeToMouse, 0)
nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK)
Toast.makeText(applicationContext,
"Action Click",Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(applicationContext,
"Not Click",Toast.LENGTH_SHORT).show()
}
nodeInfo.recycle()
}

解决方案

1. AVC权限拒绝问题

日志显示你在尝试直接读取sysfs下的GPIO节点,这是普通应用无法实现的:

  • sysfs属于系统级资源,仅系统应用或拥有root权限的应用才能访问;
  • 读取鼠标位置应该使用Android官方API,比如通过AccessibilityService的事件回调获取触摸/鼠标事件,或者监听MotionEvent,不要直接操作硬件节点。

2. rootInActiveWindow返回null问题

核心原因及修复:

  • 提前初始化nodeInfo错误:你在类初始化阶段就获取rootInActiveWindow,此时AccessibilityService可能还未完成初始化,或者当前没有活跃窗口,导致返回null。必须在需要使用时实时获取;
  • 辅助功能权限未授予:确保用户已在系统设置中为你的应用开启辅助功能权限;
  • 服务配置不正确:检查AccessibilityService的xml配置,确保声明了正确的事件类型和可访问的应用范围。

修改后的代码示例:

private fun click() {
    Log.d(TAG, "Before Click  [${cursorLayout.x}, ${cursorLayout.y}]")
    // 实时获取当前活跃窗口的根节点
    val nodeInfo = rootInActiveWindow ?: run {
        Log.d(TAG, "Error: root node is null")
        Toast.makeText(applicationContext, "无法获取窗口节点", Toast.LENGTH_SHORT).show()
        return
    }

    Log.d(TAG, "After Click..>$nodeInfo  [${cursorLayout.x}, ${cursorLayout.y}]")
    val nearestNodeToMouse = findSmallestNodeAtPoint(nodeInfo, cursorLayout.x, cursorLayout.y + 50)
    
    if (nearestNodeToMouse != null) {
        logNodeHierarchy(nearestNodeToMouse, 0)
        nearestNodeToMouse.performAction(AccessibilityNodeInfo.ACTION_CLICK)
        Toast.makeText(applicationContext, "执行点击", Toast.LENGTH_SHORT).show()
        nearestNodeToMouse.recycle() // 回收子节点
    } else {
        Toast.makeText(applicationContext, "未找到可点击节点", Toast.LENGTH_SHORT).show()
    }
    nodeInfo.recycle() // 回收根节点
}

额外检查项:

  1. 确认你的服务类继承自AccessibilityService,并在Manifest中正确注册:
<service
    android:name=".YourAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>
  1. 在accessibility_service_config.xml中配置必要参数:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged|typeTouchInteractionStart"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canPerformGestures="true"
    android:canRetrieveWindowContent="true"
    android:description="@string/accessibility_service_description" />

内容的提问来源于stack exchange,提问作者Daira Engineering

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:22:08