如何判断AccessibilityService中是否已按下后退键,onKeyDown不响应?

时间:2016-02-06 05:05:10

标签: android onbackpressed accessibilityservice

当用户按下任何系统密钥(特别是后退密钥)时,我希望能够在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 个答案:

答案 0 :(得分:1)

我怀疑你是试图从没有发送它们的软键盘上拦截这些事件。密钥事件仅可从硬件键盘可靠地发送。事实上,不鼓励从软件输入法服务手动发送事件,并且在OS的先前版本中导致潜在的恶意影响。来自Android KeyEvent文档:

  

由于软输入法可以使用多种创造性的输入文本方式,因此无法保证软键盘上的任何按键都会产生关键事件:这由IME自行决定,事实上发送此类事件是泄气。您永远不应该依赖于在软输入方法上接收任何键的KeyEvent。特别是,默认软件键盘永远不会向任何针对Jelly Bean或更高版本的应用程序发送任何键事件,并且只会将删除和返回键的某些按键发送给目标为Ice Cream Sandwich或更早版本的应用程序。请注意,无论版本如何,其他软件输入方法都可能永远不会发送关键事件。如果您需要与软件键盘进行特定交互,请考虑使用IME_ACTION_DONE等编辑器操作,因为它可以让用户更清楚地了解应用程序对按键操作的反应。

便宜的蓝牙键盘是您最好的选择。或者具有适当配置的模拟器。

编辑:

或者,您的配置文件可能有错误。在accessibilityservice.xml中,替换以下行:

android:accessibilityFlags="flagIncludeNotImportantViews"

有了这个:

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);

}