无障碍服务是一个应用程序,它给有残疾的用户或暂时无法与设备完全交互的用户提供了更好的无障碍用户交互功能。比如驾驶、照顾小孩或者在吵闹的派对上可能需要额外或者替代的交互反馈。

Android提供了标准的无障碍服务,包括TalkBack,开发人员可以创建和发布自己的无障碍服务。

Android从1.6(API 4)开始引入了构建和部署无障碍服务的能力,并在Android 4.0(API 14)进行了重大改进。Android Support Library在Android 4.0版本上增加了支持增强无障碍服务功能,这样就能够兼容到Android 1.6。Android鼓励开发者使用Support Library来广泛兼容无障碍服务,并针对Android 4.0中引入的更高级的无障碍服务功能进行开发。

清单声明和权限

提供无障碍服务的应用程序必须在其应用程序清单中包含特定声明,以便被Android系统视为无障碍服务。

无障碍服务声明

为了是应用程序的无障碍服务能够正常使用,必须在应用程序清单中application元素中包含一个service元素。另外,在service元素中,还必须包含无障碍服务的intent filter。为了兼容Android 4.1及以上版本,service元素还必须添加BIND_ACCESSIBILITY_SERVICE权限,来确保只有系统可以绑定无障碍服务。代码示例:

  <application><service android:name=".MyAccessibilityService"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"android:label="@string/accessibility_service_label"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter></service></application>

无障碍服务配置

无障碍服务还必须提供相关配置,来指定服务处理的无障碍功能事件的类型以及有关该服务的其他信息。无障碍服务的配置信息包含在AccessibilityServiceInfo 类中,无障碍服务可以在运行时使用该类实例和setServiceInfo()方法来构建和设置配置。但是,不是所有配置选项都可以使用用此方法。

从Android 4.0开始,可以在清单service元素中包含<meta-data>元素来引用一个xml无障碍配置文件,该配置文件可以设置无障碍服务的所有配置选项。代码示例:

<service android:name=".MyAccessibilityService">...<meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/accessibility_service_config" />
</service>

<meta-data>引用的xml配置文件,它是应用程序资源目录(<project_dir>/res/xml/accessibility_service_config.xml)中创建的。代码示例:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/accessibility_service_description"android:packageNames="com.example.android.apis"android:accessibilityEventTypes="typeAllMask"android:accessibilityFlags="flagDefault"android:accessibilityFeedbackType="feedbackSpoken"android:notificationTimeout="100"android:canRetrieveWindowContent="true"android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity"
/>

在运行时配置无障碍服务配置信息可以参考AccessibilityServiceInfo 类。

无障碍服务方法

无障碍服务必须继承AccessibilityService类并重写它的方法。这些方法按照Android系统调用的顺序,从服务启动调用(onServiceConnected()),运行时调用(onAccessibilityEvent(),onInterupt())到关闭服务调用(onUnbind())。

  • onServiceConnected():可选方法。该方法在系统成功连接到无障碍服务时调用。可以在该方法中为无障碍服务做一次性设置操作,包括连接到用户反馈系统服务,比如音频管理器或设备振动器。该方法还可以在运行时设置无障碍服务配置或一次性调整操作,调用setServiceInfo()方法进行设置。
  • onAccessibilityEvent():必选方法。当系统检测到与无障碍服务配置中指定事件帅选参数相匹配的AccessibilityEvent时会回调该方法。比如,当用户单击某个按钮或某个用户界面控件获得焦点时,系统会回调该方法,并传递关联的AccessibilityEvent,然后无障碍服务可以解释并向用户提供反馈。此方法可以在服务的生命周期中多次调用。
  • onInterupt():必选方法。当系统想要中断服务提供的反馈时调用此方法,通常是响应用户操作。此方法可以在服务的生命周期中多次调用。
  • onUnbind():可选方法。当系统即将关闭无障碍服务时调用此方法。使用此方法可执行任何一次性关闭程序,包括取消分配用户反馈系统服务,比如音频管理器或设备振动器。

注册无障碍事件(Event)

无障碍服务功能配置参数最重要的功能之一是允许指定服务可以处理某一类型的无障碍事件。能够指定处理某类型无障碍事件可以使无障碍功能相互协作,并使开发人员能够灵活地处理特定事件类型。事件过滤包含以下标准:

  • 包名(package name):指定无障碍服务处理哪个应用程序的无障碍事件。如果缺省此参数,则默认无障碍服务可以处理所有应用程序的事件。此参数可以在无障碍服务配置文件中设置,使用android:packageNames属性且以逗号(,)分隔列表,或者使用AccessibilityServiceInfo.packageNames成员变量进行设置。
  • 事件类型(Event Types):指定无障碍服务想要处理的事件类型。该参数可以在无障碍服务配置文件中设置,使用android:accessibilityEventTypes属性且以竖线(|)分隔列表(比如,accessibilityEventTypes="typeViewClicked|typeViewFocused"),或者使用AccessibilityServiceInfo.eventTypes成员变量进行设置。

设置无障碍服务时,请仔细考虑服务能够处理哪些事件,并只注册这些事件。由于用户一次可以激活多个无障碍服务,因此自己无障碍服务不得使用无法处理的事件。

示例代码

清单配置代码:

<service android:name=".accessibility.TaskBackService"android:label="@string/accessibility_query_window_label"android:enabled="@bool/atLeastIceCreamSandwich"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/taskbackconfig" />
</service>

xml配置代码:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"android:accessibilityEventTypes="typeAllMask"android:packageNames="com.example.android.apis"android:accessibilityFeedbackType="feedbackSpoken"android:notificationTimeout="100"android:canRetrieveWindowContent="true"android:description="@string/accessibility_query_window_description" />

无障碍服务代码:

package com.example.android.apis.accessibility;import com.example.android.apis.R;import android.accessibilityservice.AccessibilityService;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityRecord;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;import java.util.Locale;/*** This class demonstrates how an accessibility service can query* window content to improve the feedback given to the user.*/
public class TaskBackService extends AccessibilityService implements OnInitListener {/** Tag for logging. */private static final String LOG_TAG = "TaskBackService/onAccessibilityEvent";/** Comma separator. */private static final String SEPARATOR = ", ";/** The class name of TaskListView - for simplicity we speak only its items. */private static final String TASK_LIST_VIEW_CLASS_NAME ="com.example.android.apis.accessibility.TaskListView";/** Flag whether Text-To-Speech is initialized. */private boolean mTextToSpeechInitialized;/** Handle to the Text-To-Speech engine. */private TextToSpeech mTts;/*** {@inheritDoc}*/@Overridepublic void onServiceConnected() {// Initializes the Text-To-Speech engine as soon as the service is connected.mTts = new TextToSpeech(getApplicationContext(), this);}/*** Processes an AccessibilityEvent, by traversing the View's tree and* putting together a message to speak to the user.*/@Overridepublic void onAccessibilityEvent(AccessibilityEvent event) {if (!mTextToSpeechInitialized) {Log.e(LOG_TAG, "Text-To-Speech engine not ready.  Bailing out.");return;}// This AccessibilityNodeInfo represents the view that fired the// AccessibilityEvent. The following code will use it to traverse the// view hierarchy, using this node as a starting point.//// NOTE: Every method that returns an AccessibilityNodeInfo may return null,// because the explored window is in another process and the// corresponding View might be gone by the time your request reaches the// view hierarchy.AccessibilityNodeInfo source = event.getSource();if (source == null) {return;}// Grab the parent of the view that fired the event.AccessibilityNodeInfo rowNode = getListItemNodeInfo(source);if (rowNode == null) {return;}// Using this parent, get references to both child nodes, the label and the checkbox.AccessibilityNodeInfo labelNode = rowNode.getChild(0);if (labelNode == null) {rowNode.recycle();return;}AccessibilityNodeInfo completeNode = rowNode.getChild(1);if (completeNode == null) {rowNode.recycle();return;}// Determine what the task is and whether or not it's complete, based on// the text inside the label, and the state of the check-box.if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) {rowNode.recycle();return;}CharSequence taskLabel = labelNode.getText();final boolean isComplete = completeNode.isChecked();String completeStr = null;if (isComplete) {completeStr = getString(R.string.task_complete);} else {completeStr = getString(R.string.task_not_complete);}String taskStr = getString(R.string.task_complete_template, taskLabel, completeStr);StringBuilder utterance = new StringBuilder(taskStr);// The custom ListView added extra context to the event by adding an// AccessibilityRecord to it. Extract that from the event and read it.final int records = event.getRecordCount();for (int i = 0; i < records; i++) {AccessibilityRecord record = event.getRecord(i);CharSequence contentDescription = record.getContentDescription();if (!TextUtils.isEmpty(contentDescription )) {utterance.append(SEPARATOR);utterance.append(contentDescription);}}// Announce the utterance.mTts.speak(utterance.toString(), TextToSpeech.QUEUE_FLUSH, null);Log.d(LOG_TAG, utterance.toString());}private AccessibilityNodeInfo getListItemNodeInfo(AccessibilityNodeInfo source) {AccessibilityNodeInfo current = source;while (true) {AccessibilityNodeInfo parent = current.getParent();if (parent == null) {return null;}if (TASK_LIST_VIEW_CLASS_NAME.equals(parent.getClassName())) {return current;}// NOTE: Recycle the infos.AccessibilityNodeInfo oldCurrent = current;current = parent;oldCurrent.recycle();}}/*** {@inheritDoc}*/@Overridepublic void onInterrupt() {/* do nothing */}/*** {@inheritDoc}*/@Overridepublic void onInit(int status) {// Set a flag so that the TaskBackService knows that the Text-To-Speech// engine has been initialized, and can now handle speaking requests.if (status == TextToSpeech.SUCCESS) {mTts.setLanguage(Locale.US);mTextToSpeechInitialized = true;}}/*** {@inheritDoc}*/@Overridepublic void onDestroy() {super.onDestroy();if (mTextToSpeechInitialized) {mTts.shutdown();}}
}

Android无障碍服务( Accessibility Service)应用相关推荐

  1. Android 无障碍服务自动点击

    业余时间了解了Android无障碍服务的一些有趣功能,比如微信自动抢红包.应用宝的一键安装功能等.大致原理是监听手机窗体内容变化,拿到对应的View,进行点击.长按等Touch操作,下面我们就借助 A ...

  2. Android无障碍服务开发

    https://actionwind.wordpress.com/2022/04/17/android%e6%97%a0%e9%9a%9c%e7%a2%8d%e6%9c%8d%e5%8a%a1%e5% ...

  3. Android无障碍检测,Android无障碍服务检测通知

    我试图让我的应用在显示通知时进行检测.我已经在设置应用程序中启用它,并且onServiceConnected确实被调用,但是当我通过Gmail应用程序创建通知或接收电子邮件时,什么也没有发生,onAc ...

  4. 从零开始安卓无障碍服务Accessibility

    从零开始无障碍服务 文章目录 从零开始无障碍服务 前言 一.新建项目-选择Empty Activity 二.新建BaseService类和AccessService类 1. BaseService类 ...

  5. Android 无障碍服务设置

    项目中遇到需要将客户的无障碍服务设置为默认开启,无障碍服务,是可以监听界面的操作,比如:点击.拖动.界面更新等信息的,更为强大的是可以获取屏幕信息,同时具备普通Service的能力. 具体如何设置呢? ...

  6. android无障碍服务网页,android无障碍

    安卓手机无障碍服务指的是什么 许多Android用户有不同的能力(限制),这要CSS布局HTML小编今天和大家分享他们以不同的方式使用他们的Android设备.这些限制包括视力,肢体或与年龄有关,这些 ...

  7. Android的服务(Service)(三)Service客户端的绑定与跨进程

    继续上篇的分析,接下来是第三个问题"Service与其客户端的绑定如何实现,即跨进程调用问题" (一).Service的生命周期 (二).Service的自动重启问题 (三).Se ...

  8. Android的服务(Service)(一)生命周期

    本篇和接下来的几篇我们来浅析一下Android的另外一个非常重要的组件:Service,看到这里我们的脑海里都会涌现出什么词语呢?诸如:无用户交互界面,耗时后台操作,服务(级别)进程,远程调用. 1. ...

  9. android exchange服务,带有“ Service com.android.exchange.ExchangeService

    我正在用Android开发一个非常简单的应用程序.我制作了一个启动屏幕,主菜单以及一个带有单选按钮和一个按钮的页面(该按钮会根据选中的单选按钮播放声音).该应用程序运行正常(不会崩溃),但是我一直在l ...

最新文章

  1. .Net精简版数据类型
  2. 【开源推荐】进阶实战,从一款音乐播放器开始
  3. SpringBoot 2.x (12):整合Elasticsearch
  4. 全国计算机等级考试题库二级C操作题100套(第28套)
  5. 获取网站投资(融资成功)的20个自我检查
  6. php iis redis,iis windows phpstudy安装redis扩展
  7. 人间不值得?250000条数据分析李诞是不是被骂火的
  8. 109_Power Pivot客户ABC(帕累托)分析度量值写法(非计算列)
  9. 06Matplotlib数据可视化--6.2散点图
  10. anylogic 学习(1)—— anylogic 简单介绍
  11. 应届生求职简历HTML模板
  12. ldd usr bin mysql_ldd与otool
  13. JS base64编码和解码
  14. LPDDR4 layout instruction
  15. w7不显示网络计算机,Win7电脑任务栏不显示网络图标怎么办
  16. 连续翻页浏览器面临的共同问题
  17. 计算机领域的世界之最,超级计算机神威·太湖之光世界最快(中国这五年的世界之最④)...
  18. 卡通爆炸logo展示片头片尾动态视频AE模板
  19. 三星note5 android 7,国行三星note5安卓7.0降级6.0刷机包
  20. python opencv的函数cv2.LUT(src, lut, dst=None)的具体使用(LUT:查找表)

热门文章

  1. python 计算物理_计算物理期末报告
  2. 22-LTE Policy and Charging Control (PCC)
  3. AI三大主义:符号主义、联结主义、行为主义
  4. leet code: Two Sum
  5. 我的世界rpg服务器背包位置,我的世界查看玩家背包方法 如何查看玩家背包
  6. 选型宝分享什么是没有基因缺陷的信息安全体系?
  7. Android 自定义键盘布局
  8. 苹果手机10秒解除锁屏_苹果密码忘了不想刷机怎么办_苹果手机10秒解除锁屏
  9. element上传图片校验尺寸
  10. Mac 运行windows软件