android - getRootInActiveWindow() 在 onAccessibilityEvent 始终为空
问题描述
在无障碍服务中,我正在处理一个非常奇怪的情况。getRootInActiveWindow() 在 onAccessibilityEvent 中始终为空。
这是 logcat 结果:
- E/PackageName: com.google.android.packageinstaller E/EventName: TYPE_WINDOW_STATE_CHANGED====null====CONTENT_CHANGE_TYPE_UNDEFINED====null====[Packageinstaller]
- E/getRootInActiveWindow(): getRootInActiveWindow() = Null
- E/PackageName: com.google.android.packageinstaller E/EventName:
TYPE_WINDOW_STATE_CHANGED====null====CONTENT_CHANGE_TYPE_UNDEFINED====null====[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;
}
解决方案
推荐阅读
- android - 如何使用 Jetpack Compose 创建 Spannable GridView?
- linux - 大小写匹配后如何从命令行传递参数
- python - 如何在使用熊猫时要求用户输入文件的文件路径?
- flutter - Flutter 应用程序在应用程序切换器中时不呈现
- arrays - 在 Flutter 列表生成器上读取 Firestore 数组字段
- c# - 使用 Linq 从 XDocument 获取数据
- c++ - MSVC:相互导入的 C++20 模块无法编译
- sql-server - 如何确定 Azure SQL 数据库是否处于非活动状态
- shader - 如何防止 Light2D 节点改变 Godot 中精灵的颜色?
- javascript - React 将数据传递到另一个组件