Kotlin调试遇AVC权限拒绝+rootInActiveWindow返回Null问题求助
Android Kotlin应用:鼠标位置读取与模拟点击问题解决
问题描述
- 调试时持续出现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.******
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() // 回收根节点 }
额外检查项:
- 确认你的服务类继承自
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>
- 在
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
相关产品推荐
相关产品推荐

