android - 用户展开通知(状态栏)时不调用 AccessibilityEvent

标签 android events notifications accessibility accessibilityservice

我的代码从 AccessibilityService 检测到当前正在运行的应用程序,但是当用户展开状态栏时没有调用任何事件。我也尝试添加 TYPE_NOTIFICATION_STATE_CHANGED 和 TYPES_ALL_MASK 但没有任何改变。谁能帮帮我?

public void onServiceConnected() {

AccessibilityServiceInfo asi = new AccessibilityServiceInfo();
asi.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
asi.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

if (Build.VERSION.SDK_INT >= 16) {
                asi.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
}

setServiceInfo(asi);

}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getPackageName() != null) {
//my code
}

}

最佳答案

两件事。首先,当您设置无障碍服务信息时,我建议您这样做:

AccessibilityServiceInfo info = getServiceInfo();
//Set things in here
setServiceInfo(info);

现在,这不会解决这个问题。但是,这是一个很好的做法。您不想更改服务配置 XML 中的所有设置。另外,如果不让 Android 系统为您初始化信息对象,则有一些初始化选项和内容很难得到正确的。只需捕获当前的那个,根据自己的喜好调整它,然后重新设置。事实上,我没有看到您所做的任何更改可以在 service_config xml 文件中进行编辑。使用服务 XML 配置,这是一个更好的整体做法!

现在,您遇到的问题是您的配置完全错误。注意 eventTypes 是位掩码。这意味着在以下行中:

asi.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;

您是说只监听 WINDOW_STATE_CHANGED 事件。这很愚蠢。我喜欢做的是设置为 TYPE_ALL_MASK,直到我确切知道为我想要的事件触发了哪些通知。然后过滤掉那些。您还可以使用 TYPE_ALL_MASK 并使用 switch 语句进行过滤,如果您正在监听广泛不同的事件,这最终是必要的,因为不同的事件填充不同的信息(例如:并非所有事件都有源节点信息)。

现在,为什么您使用的事件类型不起作用:

TYPE_NOTIFICATION_STATE_CHANGED:此事件在添加新通知时触发,而不是在您向下滚动通知窗口时触发。

TYPE_WINDOW_STATE_CHANGED:当一个 View 占据整个屏幕并在允许访问背景内容弹出之前期望交互时触发。诸如模态对话框、菜单等之类的东西。这个定义真的很粗略,而且不一致。我相信在后端最终触发它的是需要“SYSTEM_ALERT_VIEW”权限的任何 View 的绘图,而不是我给出的定义。但是,该定义的目的是……是的,Android 辅助功能文档有点糟糕。

所以,现在我们知道问题所在了。我建议 A:不使用代码来配置您的服务信息和 B:使用 TYPE_ALL_MASK 观察所有事件,并找出最一致触发的事件。如果您观察所有事件,您可能会看到许多辅助功能事件在通知栏向下滚动时触发。选择最可靠/最适合你的那个(例如:有些内容可能会在所有内容呈现之前触发......),然后对其进行过滤。

我将从这里开始。

AndroidManifest.xml 服务配置:

<service
        android:name=".A11yService"
        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/service_config" />

    </service>

服务配置 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/accessibility_service_description"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds"
    android:canRetrieveWindowContent="true"
    android:canRequestTouchExplorationMode="true"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:notificationTimeout="100"
    android:settingsActivity="com.deque.accessibilityanalyzer.SettingsActivity"
    />

关于android - 用户展开通知(状态栏)时不调用 AccessibilityEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43592067/

相关文章:

jquery - 如何在asp.net中创建一次性通知系统

c++ - 使用 wxwidgets 不会在 C++ 中抛出事件

c# - ObjectdataSource Inserting 事件没有触发?

android - Intent 未被 singleTop Activity 拾取

android - 请求权限 READ_SMS 后,包安装程序在 Android M 中崩溃

javascript - 是否可以在不引起点击事件的情况下更改复选框状态?

android - 在通知 channel 中启用声音按钮

android - 回收 View , ScrollView 内的 ListView

android - 根据第一个 Spinner 的选择,第二个 Spinner 没有收到正确的信息

android - 如何在 KitKat 中将文件写入可移动 SD 卡(不是外部 SD 卡)?