Loading

AccessibilityService相关

介绍

AccessibilityService 是 Android 中一个用来帮助用户与应用交互的服务,特别是那些身体有障碍的用户。通过这个服务,应用可以在不需要用户直接交互的情况下接收通知和响应系统事件。

基本api组件

  1. AccessibilityService - 这是一个抽象类,你需要继承并实现其方法来创建自己的无障碍服务。
  2. onAccessibilityEvent - 当发生一个无障碍事件时,系统会调用这个方法。你需要在这里定义服务应如何响应这些事件。
  3. onInterrupt - 当服务想要中断长时间运行的反馈时调用。
  4. AccessibilityEvent - 封装了无障碍事件信息的类,比如事件类型、事件时间等。
  5. AccessibilityNodeInfo - 提供了界面组件的信息,你可以用它来查询或操作屏幕上的 UI 组件。

AccessibilityNodeInfo

AccessibilityNodeInfo 类提供了关于界面组件(如按钮、文本框等)的信息,并允许无障碍服务与这些组件进行交互。它包含了许多方法来获取和操作UI组件的状态和内容。

常用api

示例操作

AccessibilityNodeInfo rootNode = getRootInActiveWindow();
if (rootNode != null) {
    List<AccessibilityNodeInfo> resultList = rootNode.findAccessibilityNodeInfosByText("特定文本");
    for (AccessibilityNodeInfo node : resultList) {
        if (node.isClickable()) {
            node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
    }
}

示例操作

输入文字识别

通过识别组件,判断是否处于输入界面,然后提取输入的文字

配置文件

AndroidManifest.xml

<service
    android:name=".MyAccessibilityService"
    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>

accessibility_service_config.xml

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:accessibilityEventTypes="typeViewFocused|typeViewClicked|typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:notificationTimeout="100"
    android:packageNames="com.example" />

常见事件类型

服务类

继承自 AccessibilityService
public class MyAccessibilityService extends AccessibilityService{}
里面使用 onAccessibilityEvent 实现操作

onAccessibilityEvent 当触发对应事件时触发该函数

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo source = event.getSource();
    if (source != null) {
        switch (event.getEventType()) {
            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
                // 检查焦点是否在文本编辑框上
                if (source.getClassName().equals("android.widget.EditText")) {
                    CharSequence text = source.getText();
                    if (text != null) {
                        // 处理或存储文本
                    }
                }
                break;
        }
    }
}

检测弹窗,提取文字图标

onAccessibilityEvent

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED ||
        event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
        AccessibilityNodeInfo rootNode = getRootInActiveWindow();
        if (rootNode != null) {
            findAdsInWindow(rootNode);
        }
    }
}

findAdsInWindow

private void findAdsInWindow(AccessibilityNodeInfo rootNode) {
    List<AccessibilityNodeInfo> adNodes = rootNode.findAccessibilityNodeInfosByText("广告");
    for (AccessibilityNodeInfo node : adNodes) {
        // 提取广告中的文字
        CharSequence adText = node.getText();
        if (adText != null) {
            Log.d("Ads", "广告文本: " + adText.toString());
        }

        // 提取广告中的图标
        List<AccessibilityNodeInfo> imageNodes = node.findAccessibilityNodeInfosByViewId("id/icon"); // 假设广告图标的id是'icon'
        for (AccessibilityNodeInfo imgNode : imageNodes) {
            // 图标提取逻辑,截图或使用其他方法
            Log.d("Ads", "找到广告图标");
        }
    }
}

posted @ 2024-06-25 14:07  F丶cat  阅读(313)  评论(0)    收藏  举报