用AccessibilityService实现自动清理近期任务列表(Recent)功能

目前在写Android端微信全自动化的项目,业务逻辑上需要定期清理Recent列表杀死微信,来实现对应用的运行环境的初始化,决定用AccessibilityService来实现。
实现如下——

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:notificationTimeout="100"
    android:description="@string/accessibility_description" 
    android:packageNames="com.tencent.mm,com.android.systemui" />

实现服务

执行逻辑:如果监听触发,则先按home键回到桌面,然后按recent(menu)键显示最近任务列表,然后找到清理按钮、点击清理按钮。

package com.sk.androidauto.service;

import java.util.List;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.os.SystemClock;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

public class MyAccessibilityService extends AccessibilityService {

    private static final String TAG = "MyAccessibilityService";
    private static final int SLEEPTIME = 2000;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        //此处写事件的处理,常用eventType和className来做判断。
        int eventType = event.getEventType();
        String className = event.getClassName().toString();
        Log.d(TAG, "当前事件类型:" + eventType);
        Log.d(TAG, "当前执行类名:" + className);
        //根据不同的eventType和className,来进行具体的事件处理
        switch (eventType) {
        case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
            monitor();
            break;
        }

    }

    @Override
    public void onInterrupt() {

    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
    }

    /**
     * 系统桌面,点击菜单键时候,弹出的清理按键id
     */
    private static final String systemuiClearBtnId = "com.android.systemui:id/clearButton";
    /**
     * 点击系统菜单键,清理运存
     */
    private void clearMemory() {
        SystemClock.sleep(SLEEPTIME);
        AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
        if (nodeInfo != null) {
            List<AccessibilityNodeInfo> infos = nodeInfo.findAccessibilityNodeInfosByViewId(systemuiClearBtnId);
            if (infos != null && infos.size() > 0) {
                AccessibilityNodeInfo clearBtn = infos.get(0);
                clearBtn.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
            nodeInfo.recycle();
        }
    }


    public void monitor() {
        SystemClock.sleep(SLEEPTIME);
        performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME);
        SystemClock.sleep(SLEEPTIME);
        performGlobalAction(AccessibilityService.GLOBAL_ACTION_RECENTS);
        clearMemory();
    }
}

注册服务

<service
    android:name="com.sk.androidauto.service.MyAccessibilityService"
    android:enabled="true"
    android:exported="true"
    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_systemui" />
</service>

触发监听

public void accessibilityserviceClear(View view) {
    if (!AccessibilityServiceUtil.isAccessibilitySettingsOn(this, MyAccessibilityService.class)) {
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        startActivity(intent);
    } else {
        //调起微信,触发AccessibilityService对微信的监听
        callWX();
    }
}

很简单的一个小功能,没有使用过AccessibilityService的可以参考下:‘
Android自动化之AccessibilityService模拟操作(快速集成)
Android自动化之AccessibilityService模拟操作(经验总结)


版权声明:本文为questions000原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。