android - onAccessibilityEvent 中的 getRootInActiveWindow() 始终为 null

标签 android accessibilityservice

在无障碍服务中,我正在处理一个非常奇怪的情况。 onAccessibilityEvent 中的 getRootInActiveWindow() 始终为 null。

这是 logcat 结果:

  • E/PackageName:com.google.android.packageinstaller E/EventName: TYPE_WINDOW_STATE_CHANGED====null====CONTENT_CHANGE_TYPE_UNDEFINED====null====[软件包安装程序]
  • E/getRootInActiveWindow(): getRootInActiveWindow() = Null
  • E/PackageName:com.google.android.packageinstaller E/EventName:
    TYPE_WINDOW_STATE_CHANGED====空====CONTENT_CHANGE_TYPE_UNDEFINED====空====[3D 动态壁纸,您要卸载此应用程序吗?,取消,确定]
  • E/getRootInActiveWindow(): getRootInActiveWindow() = Null

消息 getRootInActiveWindow(): getRootInActiveWindow() = Null 是在 findAlertDialogNode 开始时生成的,此时应用程序将找到“确定”按钮。

我在这里做错了什么?感谢您的帮助。

代码:

无障碍服务 XML

<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityEventTypes="typeAllMask"
android:packageNames="com.google.android.packageinstaller"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"
/>

onAccessibilityEvent

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    String eventText = getTypeName(event.getEventType()) + "===="
            + event.getContentDescription() +  "===="
            + getContentChangeTypesName(event.getContentChangeTypes())   +  "===="
            + event.getSource()  +  "===="
            + event.getText(); //TODO REMOVE
    if (event.getPackageName() != null) Log.e("PackageName", event.getPackageName().toString()); //TODO REMOVE
    Log.e("EventName", eventText); //TODO REMOVE

    PreferenceManager preferenceManager = new PreferenceManager(mContext);
    if (!preferenceManager.isCleanUpProcessStarted()) return;
    if (!preferenceManager.isScreenBlocked()) return;

    List<App> selectedAppsForDeletionList = preferenceManager.getSelectedAppsForDeletion();
    if (selectedAppsForDeletionList == null || selectedAppsForDeletionList.size() == 0) return;

    selectedAppPackageNameForDeletion = null;
    AccessibilityNodeInfo OkButton = findAlertDialogNode(getRootInActiveWindow(), selectedAppsForDeletionList);
    if (OkButton != null) {
        OkButton.performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.getId());
        removePackageFromDeletionList(selectedAppsForDeletionList, selectedAppPackageNameForDeletion);
        Log.e("PackageName Deleted ", selectedAppPackageNameForDeletion); //TODO REMOVE
        startSelectedAppsForDeletion();
    }
}

findAlertDialogNode

private AccessibilityNodeInfo findAlertDialogNode(AccessibilityNodeInfo root, List<App> selectedAppsForDeletionList) {

        String packageName = null;
        if (root == null) {
            Log.e("getRootInActiveWindow()", "getRootInActiveWindow() = Null "); //TODO REMOVE
            return null;
        }

        Deque<AccessibilityNodeInfo> deque = new ArrayDeque<>();
        deque.add(root);

        while (!deque.isEmpty()) {
            AccessibilityNodeInfo node = deque.removeFirst();
            if (node == null) return null;

            if (node.getClassName().equals("android.widget.TextView")) {
                if (packageName == null)
                    packageName = findPackageToUninstall(node, selectedAppsForDeletionList);
            }

            if (node.getActionList().contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)) {
                if (node.getText() != null) {
                    if (node.getText().equals("OK")) {
                        if (packageName != null) {
                            //removePackageFromDeletionList(selectedAppsForDeletionList, packageName);
                            Log.e("PackageName Selected For Deletion ", packageName); //TODO REMOVE
                            selectedAppPackageNameForDeletion = packageName;
                            return node;
                        }
                    }
                }
            }

            for (int i = 0; i < node.getChildCount(); i++) {
                deque.addLast(node.getChild(i));
            }
        }
        return null;
    }

最佳答案

您需要 xml 中的这两行

android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"

android:canRetrieveWindowContent="true"

它对我有用,以防万一,这是我的 xml:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeWindowContentChanged"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
    android:canPerformGestures="true"
    android:canRequestFilterKeyEvents="false"
    android:canRetrieveWindowContent="true"
    android:description="@string/user_permission_accessibility_description"
    android:notificationTimeout="1000" />

关于android - onAccessibilityEvent 中的 getRootInActiveWindow() 始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58684577/

相关文章:

Android Studio,RecyclerView 在启动时使我的应用程序崩溃

java - Eclipse Translator App - 单独翻译单词 - 不包含前面或后面的字符

android - 如何在截击中发送 json 数组作为 post 请求?

java - 指定 AccessibilityService 功能

android - 使用无障碍服务

java - 如何提高android中输入命令的速度?

android - ReSTLet 错误 :duplicate files during packaging of APK in androidstudio

android - 为什么 AccessibilityService 的 onAccessibilityEvent(..) 方法多次读取同一个 View ?

java.lang.IllegalStateException : android.accessibilityservice.AccessibilityService.getSystemService(AccessibilityService.java:1602)

android - 使用 AccessibilityService 中的 AccessibilityNodeInfo 执行滚动