vivo、OPPO设备授予自启动权限后AccessibilityService仍自动禁用问题
问题根因
你遇到的问题分两类:1. 代码本身的错误导致服务异常触发系统权限回收;2. vivo、OPPO等国内定制ROM的后台进程管控策略主动禁用异常/耗电的无障碍权限。
修复方案
1. 先修正代码中的致命错误
你当前MyAccessibilityService里的onAccessibilityEvent方法存在严重的对象泄漏和逻辑错误:
错误点:反复调用
AccessibilityEvent.obtain()创建新的空事件对象,完全没有使用传入的event参数获取事件记录,会导致大量未回收的事件对象占用内存,触发系统的异常服务检测,直接回收你的无障碍权限。
修正后的代码逻辑如下:
@SuppressLint("WrongConstant") @Override public void onAccessibilityEvent(AccessibilityEvent event) { if (event == null) return; try { AccessibilityNodeInfo rootNode = event.getSource(); if (rootNode != null) { if (event.getEventType() == AccessibilityEvent.WINDOWS_CHANGE_REMOVED) { Log.d("tah", "event: " + event.getText().toString() ); } // 修正:直接用传入的event获取记录数,不要新obtain事件 int count = event.getRecordCount(); Log.i("TAG", "count=" + count); for (int i = 0; i < count; i++) { // 修正:从当前event取Record,不要新obtain AccessibilityRecord record = event.getRecord(i); Log.i("TAG", "className=" + record.getClassName()); AccessibilityNodeInfo node = record.getSource(); if (node != null) { AccessibilityNodeInfo parentNode = node.getParent(); if (parentNode != null) { // 增加判空,避免空指针 Log.i("TAG", "parent=" + parentNode.getClassName()); } int childCount = node.getChildCount(); for (int j = 0; j < childCount; j++) { AccessibilityNodeInfo childNode = node.getChild(j); if (childNode != null) { // 增加判空 Log.i("TAG", "child=" + childNode.getClassName()); } } // 补充:用完node要recycle,避免内存泄漏 node.recycle(); } } // 补充:用完rootNode要recycle rootNode.recycle(); } } catch (Exception e) { Log.e("tag", "Exception: ", e); // 打印完整栈,方便排查问题 } } @Override public void onInterrupt() { Log.e("tag", "onInterrupt: " ); }
2. 优化无障碍服务配置
修改accessibility_service_config.xml,添加保活相关的flags,避免系统误判为闲置服务:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeAllMask" android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagRequestTouchExplorationMode|flagReportViewIds" android:accessibilityFeedbackType="feedbackGeneric" android:notificationTimeout="100" android:canRetrieveWindowContent="true" android:canRequestFilterKeyEvents="true" android:foregroundServiceType="specialUse" android:settingsActivity="" />
3. 适配国内厂商后台管控策略
vivo、OPPO除了自启动权限,还需要引导用户开启额外权限:
- 关闭系统的耗电优化/耗电保护:允许应用后台耗电、加入高耗电允许名单
- 加入内存清理白名单:避免一键清理的时候杀死你的应用进程
- 允许应用后台弹出界面、悬浮窗权限(部分ROM需要这个权限才能维持后台服务优先级)
4. 增加服务保活与状态检测
- 给你的应用绑定一个前台服务,常驻通知栏,把服务优先级提高到前台级别,降低被系统回收的概率
- 增加定时检测逻辑:每隔1~2分钟检测一次AccessibilityService是否处于运行状态,如果发现权限被关闭,弹出引导框提示用户重新开启无障碍权限,直接跳转系统的无障碍权限设置页
内容的提问来源于stack exchange,提问作者karan
相关产品推荐
相关产品推荐

