如何在AccessibilityService中确定是否按下了后退键,onKeyDown没有响应?

3

我希望在AccessibilityService中能够知道用户何时按下任何系统键,特别是返回键。我已经重写了onKeyEvent方法,但它完全没有反应,但我可以从onAccessibilityEvent中获取所有事件。

@Override
public boolean onKeyEvent(KeyEvent event) {
    Log.e(TAG, "------------------- onKeyEvent ----------------------------");
    return super.onKeyEvent(event);
}

以下是我的配置文件,我正在监视AccessibilityService子项目和实际应用程序包。
包含AccessibilityService的子项目的Manifest.xml
<?xml version="1.0" encoding="utf-8"?>

...

<service android:name="com.foo.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/accessibilityservice" />
</service>

accessibilityservice.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>

<accessibility-service
xmlns:tools="http://schemas.android.com/tools"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagIncludeNotImportantViews"
xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/emachine_accessibility_service_description"
android:settingsActivity="com.foo.services.MyAccessibilityService"
tools:ignore="UnusedAttribute"
android:canRetrieveWindowContent="true"
android:canRequestFilterKeyEvents="true"
android:canRequestTouchExplorationMode="true"/>

是的,com.foo.services.MyAccessibilityService 在系统辅助功能设置下已经处于“开启”状态。

添加了

    android:canRequestFilterKeyEvents="true"
android:canRequestTouchExplorationMode="true"

在上面的 accessibility.xml 中,相应的onServiceConnected也是以编程方式添加的。

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        info.flags |= AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
        info.flags |= AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
        info.flags |= AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
    }

没有积极的结果。
1个回答

1
我怀疑您正在尝试拦截来自未发送它们的软键盘的这些事件。键事件只能可靠地从硬件键盘发送。实际上,手动从软件输入方法服务发送事件是不被鼓励的,并且在操作系统的早期版本中可能导致潜在的恶意影响。根据Android KeyEvent文档:“由于软输入方法可以使用多种有创意的方式输入文本,因此不能保证软键盘上的任何按键都会生成键事件:这取决于IME的决定,并且事实上发送这样的事件是不被鼓励的。您永远不应该依赖于接收软输入法上任何键的KeyEvents。特别是,默认软键盘将永远不会向任何针对Jelly Bean或更高版本的应用程序发送任何键事件,并且仅会向针对Ice Cream Sandwich或更早版本的应用程序发送一些删除和返回键的按压事件。请注意,其他软件输入方法可能永远不会发送键事件,无论版本如何。如果需要与软键盘进行特定交互,请考虑使用编辑器操作(例如IME_ACTION_DONE),因为它可以使用户更清楚地了解您的应用程序如何对按键作出反应。”
廉价的蓝牙键盘是您最好的选择。或者具有适当配置的模拟器。
编辑:

或者您的配置文件中有错误。在您的accessibilityservice.xml文件中,将此行替换为:

android:accessibilityFlags="flagIncludeNotImportantViews"

With this:

android:accessibilityFlags="flagIncludeNotImportantViews|flagRequestFilterKeyEvents"

您也可以在辅助功能服务代码中实现相同的功能。
protected void onServiceConnected() {
    super.onServiceConnected();

    AccessibilityServiceInfo tempInfo = getServiceInfo();
    tempInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
    tempInfo.flags |= AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS;
    setServiceInfo(tempInfo);

}

完全不需要考虑软键盘,只需关注系统返回按键。在可访问性服务中,我想知道何时按下系统返回键,即回到上一个活动。我不是指输入法类型方法中的后退空格。 - Peter Birdsall
同样的逻辑适用。系统不需要在后退箭头按下时发送关键事件。您依赖于不是必需的实现细节。要侦听此内容,必须为辅助功能服务添加特殊事件,但这并不存在。长话短说,您无法可靠地这样做。 - MobA11y
我只想知道用户何时按下返回键并通过正常的后退堆栈从Activity B返回到Activity A。换句话说,如果AccessessibiltyService是一个Activity,我想知道是否已经进入了onBackPressed()。我不希望改变onBackPressed()的执行,只是想知道它是否发生过。 - Peter Birdsall
知道后退键已经被按下,以及知道你从A活动到B活动是不同的。前者是一个更严格的要求。那么这两者哪个呢? - MobA11y
嘿,看看这些编辑。当我回答另一个非常相似的问题时,我刚刚注意到了这一点。乍一看,我以为你的配置是正确的,但事实并非如此。你错过了某些东西。在Droid Turbo上,这对我起作用,但是我关于这种方法与不同硬件设置相关的不稳定性的评论仍然适用,所以不能保证! - MobA11y
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接