Android AccessibilityService

一、声明无障碍服务

在AndroidManifest.xml中声明无障碍服务

 <service
     android:name=".MyAccessibilityService"
     android:enabled="true"
     android:exported="true"
     android:label="无障碍服务"
     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>

二、配置

在res下xml目录中新建xml配置文件

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagReportViewIds|flagIncludeNotImportantViews|flagRetrieveInteractiveWindows"
    android:canPerformGestures="true"//指定可以通过无障碍服务模拟手势
    android:canRetrieveWindowContent="true" />//指定可以通过无障碍获取窗口内容

EventTypes:指定要监听的事件类型
typeAllMask:所有事件,
typeViewClicked:视图点击事件,
typeViewFocused:视图获取焦点使劲啊,
typeViewSelected:视图被选择事件,
typeViewTextChanged:视图文本内容发生变化事件,
typeWindowStateChanged:窗口状态发生变化事件,
typeNotificationStateChanged:通知状态发生变化事件,
typeViewLongClicked:视图长按事件,
typeWindowContentChanged:窗口内容发生变化事件,
typeTouchExplorationGestureEnd:触摸探索手势结束事件,
typeGestureDetectionEnd:手势检测结束事件。
Flags:无障碍服务的标志位
flagDefault:默认标志位,表示无障碍服务使用默认行为。
flagIncludeNotImportantViews:包括非重要视图。默认情况下,无障碍服务会忽略标记为非重要的视图,使用此标志位可以包括这些视图。
flagReportViewIds:报告视图的ID。使用此标志位,无障碍服务将报告视图的ID,以便辅助功能工具可以识别和处理特定的视图。
flagRequestEnhancedWebAccessibility:请求增强的网页辅助功能。当应用中存在WebView时,使用此标志位可以启用对网页内容的增强访问能力,以提供更好的辅助功能支持。
flagRequestFilterKeyEvents:请求过滤按键事件。当无障碍服务需要对按键事件进行过滤时,可以使用此标志位。
flagRequestTouchExplorationMode:请求触摸探索模式。使用此标志位,无障碍服务可以进入触摸探索模式,使用户能够通过滑动和探索屏幕来执行操作。

三、创建无障碍服务类

class MyAccessibilityService : AccessibilityService() {
    override fun onServiceConnected() {
        // 在服务连接时执行初始化操作
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        // 处理接收到的无障碍事件
    }

    override fun onInterrupt() {
        // 当服务中断时执行清理操作
    }
}

四、执行模拟手势操作

通过点击特定位置坐标,通过时间设置可以实现点击和长按

public void performClick() {
    GestureDescription.Builder builder = new GestureDescription.Builder();
    Path p = new Path();
    float x = 200.f;
    float y = 200.f;
    p.moveTo(x, y);
    //p.lineTo(x1,y1);//可以实现滑动
    builder.addStroke(new GestureDescription.StrokeDescription(p, 0L, 100L));
    GestureDescription gesture = builder.build();
    MyAccessibilityService.getService().dispatchGesture(gesture, new AccessibilityService.GestureResultCallback() {
        @Override
        public void onCompleted(GestureDescription gestureDescription) {
            super.onCompleted(gestureDescription);
        }

        @Override
        public void onCancelled(GestureDescription gestureDescription) {
            super.onCancelled(gestureDescription);
        }
    }, null);
}

五、执行模拟点击功能

通过获取页面信息执行点击

private AccessibilityNodeInfo findAccessibilityNodeInfosByViewId(AccessibilityNodeInfo rootNode, String resourceId) {
    if (rootNode == null) {
        return null;
    }
    if (resourceId.equals(rootNode.getViewIdResourceName())) {
        return rootNode;
    }
    for (int i = 0; i < rootNode.getChildCount(); i++) {
        AccessibilityNodeInfo childNode = rootNode.getChild(i);
        AccessibilityNodeInfo targetNode = findAccessibilityNodeInfosByViewId(childNode, resourceId);
        if (targetNode != null) {
            return targetNode;
        }
    }
    return null;
}

public boolean performClickNode(String nodeId) {
    MyAccessibilityService service = MyAccessibilityService.getService();
    AccessibilityNodeInfo rootNode = service.getRootInActiveWindow();
    AccessibilityNodeInfo buttonNode = findAccessibilityNodeInfosByViewId(rootNode, nodeId);
    if (null == buttonNode) return false;
    boolean clickResult = buttonNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    return clickResult;
}

//返回上一级
public boolean performActionBack() {
	MyAccessibilityService service = MyAccessibilityService.getService()
	return service.performGlobalAction(GLOBAL_ACTION_BACK);
}

你可能感兴趣的:(Android,android)