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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:57:03