ClearProcesses Save

利用无障碍服务(AccessibilityService)批量清理后台进程

Project README

AccessibilityService

1.简介
public abstract class AccessibilityService extends Service

java.lang.Object
 ↳ android.content.Context
   ↳ android.content.ContextWrapper
     ↳ android.app.Service
       ↳ android.accessibilityservice.AccessibilityService

无障碍服务旨在帮助身心有障碍的用户使用Android设备和应用。无障碍服务在后台运行,当无障碍事件被激活时系统会执行AccessibilityServiceonAccessibilityEvent(AccessibilityEvent event)方法。这些事件表示在用户界面中的一些状态的改变,例如:焦点的改变、按钮被点击等。这类服务可以有选择性地请求查询活动窗口的内容。无障碍服务的开发需要继承AccessibilityService和实现它的抽象方法。

2.使用
public class YourService extends AccessibilityService {
    @Override public void onAccessibilityEvent(final AccessibilityEvent event) {
        //TODO ...
    }
    @Override public void onInterrupt() {
	      //TODO ...
    }
}

onAccessibilityEvent方法中,通过AccessibilityEventgetSource方法获取AccessibilityNodeInfoUI节点信息

AccessibilityNodeInfo nodeInfo = event.getSource();

通过AccessibilityNodeInfofindAccessibilityNodeInfosByTextfindAccessibilityNodeInfosByViewId方法获取你感兴趣的UI子节点信息

List<AccessibilityNodeInfo> nodeInfoList = event.getSource().findAccessibilityNodeInfosByText("强行停止");

通过AccessibilityNodeInfoperformAction方法来模拟用户点击事件

nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);

使用AccessibilityService之前需要判断一下当前是否已经授权

private boolean checkEnabledAccessibilityService() {
    List<AccessibilityServiceInfo> accessibilityServices =
            mAccessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
    for (AccessibilityServiceInfo info : accessibilityServices) {
        if (info.getId().equals(SERVICE_NAME)) {
            return true;
        }
    }
    return false;
}

如果没有授权,需要到系统设置页面进行设置

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
3.属性配置

在资源文件res目录下新建一个xml文件夹,创建AccessibilityService配置文件your_config.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_name"
    android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
    android:packageNames="com.android.settings"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:notificationTimeout="500"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    />
属性名称 属性简介
android:accessibilityEventTypes 指定我们在监听窗口中可以模拟哪些事件
android:accessibilityFeedbackType 指定无障碍服务的反馈方式
android:accessibilityFlags 指定额外的标志
android:canRetrieveWindowContent 指定是否允许我们的程序读取窗口中的节点和内容
android:description 系统设置无障碍页面显示的选项名称
android:notificationTimeout 两个相同类型事件发送的时间间隔,单位毫秒
android:packageNames 指定监听的应用程序包名,多个以,隔开
更多属性介绍请参考:AccessibilityServiceInfo
4.AndroidManifest配置
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ... >

    <application ...>
        ...
        <service
            android:name=".YourService"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <-- 需要用到BIND_ACCESSIBILITY_SERVICE这个权限 -->
            <intent-filter>
                <-- 有了这个action,用户才能在设置里面看到我们的服务 -->
                <action android:name="android.accessibilityservice.AccessibilityService"/>
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/your_config"/>
        </service>
	...
    </application>

</manifest>

清理后台进程

1.获取后台进程

通过ActivityManagergetRunningAppProcessesgetRunningServices方法获取后台运行的应用程序、服务列表

ActivityManager mActivityManager = (ActivityManager) mAppContext.getSystemService(Context.ACTIVITY_SERVICE);
//返回在设备上运行的应用程序的进程的列表
List<ActivityManager.RunningAppProcessInfo> appProcessInfos = mActivityManager.getRunningAppProcesses();
//返回当前正在运行的服务的列表
List<ActivityManager.RunningServiceInfo> serviceInfos = mActivityManager.getRunningServices(yourCount);
2.进入应用程序详情页面
private void showPackageDetail(String packageName){
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts(PACKAGE, packageName, null);
    intent.setData(uri);
    startActivity(intent);
}
3.模拟强行停止操作
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onAccessibilityEvent(final AccessibilityEvent event) {
    if(null == event || null == event.getSource()) { return; }
    if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED &&
            event.getPackageName().equals(PACKAGE)){
        final CharSequence className = event.getClassName();
        if(className.equals(NAME_APP_DETAILS)){ //模拟点击强行停止按钮
            simulationClick(event, TEXT_FORCE_STOP);
            performGlobalAction(GLOBAL_ACTION_BACK);
        }
        if(className.equals(NAME_ALERT_DIALOG)){ //模拟点击弹窗的确认按钮
            simulationClick(event, TEXT_DETERMINE);
            performGlobalAction(GLOBAL_ACTION_BACK);
        }
    }
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void simulationClick(AccessibilityEvent event, String text){
    List<AccessibilityNodeInfo> nodeInfoList = event.getSource().findAccessibilityNodeInfosByText(text);
    for (AccessibilityNodeInfo node : nodeInfoList) {
        if (node.isClickable() && node.isEnabled()) {
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
    }
}

关于

License

Copyright 2015 classic

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Open Source Agenda is not affiliated with "ClearProcesses" Project. README Source: qyxxjd/ClearProcesses
Stars
76
Open Issues
1
Last Commit
7 years ago

Open Source Agenda Badge

Open Source Agenda Rating