AccessibilityService 已启动,但在 JellyBean 上未收到 AccessibilityEvents

Posted

技术标签:

【中文标题】AccessibilityService 已启动,但在 JellyBean 上未收到 AccessibilityEvents【英文标题】:AccessibilityService is started but does not receive AccessibilityEvents on JellyBean 【发布时间】:2012-08-14 17:33:53 【问题描述】:

我有一个 AccessibilityService 可以读出任何传入的通知。它在 ICS 及以下版本中运行良好,但在 JB 中停止运行。

下面是Manifest和代码:

<service
        android:name=".Services.InstantMessengerJb"
        android:enabled="@bool/is_post_jb"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
        tools:ignore="ExportedService" >
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibility_service_config" />

        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
    </service>

@Override
public void onAccessibilityEvent(AccessibilityEvent event) 
    SettingsClass.logMe(tag, "New event!");
    new AccessibilityProcessing(this, event);


@Override
protected void onServiceConnected() 
    if (isInit) 
        return;
    
    SettingsClass.logMe(tag, "We are connected!");
    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
    info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
    setServiceInfo(info);
    isInit = true;

如前所述,它确实可以在所有 preJB 设备上运行,但在 JB 上服务启动(我得到“我们已连接”),但没有触发任何事件。

代码有什么问题吗?

【问题讨论】:

我发现它有效,但前提是定义了 declarativley。您还需要添加新的绑定权限并有一些条件逻辑来确定是否在果冻豆中运行,否则旧手机将无法使用新的绑定参数运行。我会试着一起举个例子。 我注意到在某些声明了绑定许可的设备上仍然可以使用冰淇淋沙,但不适用于生姜面包。 啊.. 很好的更正:绑定可访问性服务 >= api 16,但看起来它被忽略并且仍然在 api 15 中工作 【参考方案1】:

这就是我让它工作的方式:

    子类化服务类,使其有 2 个版本。

    在 res/values 目录下有一个 bools.xml 文件,在 res/values-v16 目录下也有一个

    在 v16 中将 is_jelly_bean 布尔值设置为 true,在 res/values 目录版本中设置 is_not_jelly_bean

    在清单中有这样的东西

    <service android:name=".service.MainRunningService" android:enabled="@bool/is_jelly_bean"
        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/accessibilityservice" />
    </service>
    
    <service android:name=".service.MainRunningServicePreJellyBean" 
        android:enabled="@bool/is_not_jelly_bean">
        <intent-filter >
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
    
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice" />
    </service>
    

在res/xml目录调用accessibilityservice.xml中有一个无障碍服务xml文件

里面有这样的东西:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeNotificationStateChanged"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:description="@string/description_that_shows_on_the_accessibility_page" />

【讨论】:

感谢您的回答!请注意,我已经为 JB 使用了修改后的服务(请参阅代码),但我会尝试使用 XML 文件中的服务描述并报告回来。 这就是我发现的不同之处。我不知道为什么代码版本似乎不起作用。 @RupertRawnsley 我猜你的目标 sdk 设置为 17。目前我只使用 16 的目标,它仍然有效。 @ECEsurfer - 不,遗憾的是不在果冻豆中。我确定这是android中的一个错误 为了让它工作,我必须向 is_jelly_bean &lt;intent-filter&gt; 添加一个 &lt;category&gt; 元素。我以 TalkBack 为例,从 its source 中拉出类别【参考方案2】:

我在 Android 4.1.1 中遇到了这个问题。直到我禁用并重新启用无障碍服务后,无障碍服务才收到事件。

为了解决这个问题,我在setServiceInfo()accessibilityservice.xml 中定义了无障碍服务参数。

在我的例子中,没有必要定义两个不同的依赖于 Android 版本的无障碍服务。

【讨论】:

以上是关于AccessibilityService 已启动,但在 JellyBean 上未收到 AccessibilityEvents的主要内容,如果未能解决你的问题,请参考以下文章

android开发中在 AccessibilityService 中启动activity失败

抢红包软件背后的 Accessibility 服务及启动原理

AccessibilityService从入门到出轨

IMS:AccessibilityService辅助服务拦截注入Input事件

IMS:AccessibilityService辅助服务拦截注入Input事件

Android AccessibilityService 事件分发原理