12

我想在我的 Android 应用程序中实现一个辅助功能服务,它可以执行以下操作:

=>在任何应用程序中获取屏幕点击/点击。

=>获取被点击/点击的视图。

最初我认为由于安全原因不可能这样做,但在做一些研究时,我遇到了一个应用程序(本机剪贴板),它可以做以下事情:

=>检测EditText任何应用程序对 s 的点击

=>将值(字符串)添加到那些EditTexts。

我还看到了谷歌的对讲,它会说出你点击的任何内容。要让它说话,它需要跨应用程序访问视图(以获取文本)。

这些应用程序显然利用“辅助功能服务”来做到这一点,但我想知道如何实现它?

我主要为我需要实现的事情找到教程或东西,但我正在努力寻找一些为我的应用程序实现辅助功能服务的东西。我确实访问了 Android 官方文档,这对于像我这样的新手来说太技术性了。(我最初更喜欢从 Youtube、SO 和教程网站学习)。如果您可以将我指向其他一些涵盖这些内容的教程,那也很棒。

4

1 回答 1

12

无障碍服务的文档记录很差,但我创建了一些无障碍服务样板代码,用于设置启动项目并记录基本回调。考虑到您的具体问题,我认为您会关心这里的一些代码。脚手架,项目设置等我离开了回购。

下面是 onAccessibilityEvent 回调。这是您将侦听不同类型事件的地方,也是大多数情况下获取屏幕内容的最方便的地方。不过,作为无障碍服务,您也不必等待事件。您可以轻松地生成一个 AsynTask 并以某种间隔抓住它。

public void onAccessibilityEvent(AccessibilityEvent event) {
    CLog.d(event.toString());

    switch (event.getEventType()) {
        //On Gesture events print out the entire view heirarchy!

        case AccessibilityEvent.TYPE_GESTURE_DETECTION_START:
            CLog.d(A11yNodeInfo.wrap(getRootInActiveWindow()).toViewHeirarchy());

        case AccessibilityEvent.TYPE_VIEW_CLICKED:
            CLog.d(event.getSource().toString());

        default: {
            //The event has different types, for you, you want to look for "action clicked"
            if (event.getSource() != null) {
                CLog.d(A11yNodeInfo.wrap(event.getSource()).toViewHeirarchy());
            }
        }
    }
}

我将为此指出一点配置,因为它非常重要。辅助功能服务最好通过通过 Manifest 文件连接到您的服务的 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="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:canRequestTouchExplorationMode="true"
android:accessibilityFeedbackType="feedbackSpoken"
android:notificationTimeout="100"
android:settingsActivity="com.moba11y.basicaccessibilityservice.SettingsActivity"
/>

对你来说,重要的部分是canRetrieveWindowContent="true"accessibilityEventTypes="typeAllMask"。我喜欢的一个设计是确保你抓住你想要的最少的事件类型。不同的无障碍事件报告的结果大相径庭。例如,许多事件从 getSource() 返回“null”。这迫使您为此添加大量过滤器,否则可能会出现空指针异常。这很烦人。

您需要的最后一点是辅助功能操作。这就是允许您模拟点击、长按并将文本添加到可编辑文本视图的原因。下面是允许您执行此操作的代码。

public void onAccessibilityEvent(AccessibilityEvent event) {
    AccessibilityNodeInfo source = event.getSource();
    if (source != null & event.getClassName().equals("android.widget.EditText")) {
        Bundle arguments = new Bundle();
        arguments.putCharSequence(
            AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,"some value");
        source.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
    }
}

https://github.com/chriscm2006/Android-Accessibility-Service-Boilerplate

于 2017-04-24T15:30:35.400 回答