概述
无障碍服务
什么是无障碍?为什么需要无障碍?
让应用使用起来没有障碍。Android应用的目标是让所有人都可以使用,包括但不限于视力受损、色盲、听力受损、精细动作失能的人。要想这些有无障碍需求的用户有更好的体验,那么开发应用就要多考虑无障碍功能。
Android无障碍服务
无障碍服务是 Android框架的一项功能,旨在为了给使用Android设备的残障人士提供交互反馈,让他们能够更方便的使用Android设备。
常见无障碍服务示例
- 开关访问:允许行动不便的 Android 用户使用一个或多个开关与设备进行交互。
- 语音访问:允许行动不便的 Android 用户使用语音命令控制设备。
- Talkback:视力受损或盲人用户常用的屏幕阅读器。
如何构建自己的无障碍服务?
1.新建TestAccessibilityService.java类继承AccessibilityService;
import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;
/**
* @author fenghaitao
* @time 2021/8/30 12:08
*/
public class TestAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
}
@Override
public void onInterrupt() {
}
}
2.在/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"
/>
字段说明:
- description 说明
- packageNames 要监控的应用包名,多个应用用“,”隔开;
- accessibilityEventTypes 此服务希望接收的事件类型;
- accessibilityFlags 辅助功能附加的标志,多个使用 ’ | '分隔,如flagRequestFilterKeyEvents 能够监听到系统的物理按键;
- accessibilityFeedbackType 反馈类型,有语音、视觉、触觉等;
- notificationTimeout 同一类型的两个辅助功能事件发送到服务的最短间隔(毫秒,两个辅助功能事件之间的最小周期);
- canRetrieveWindowContent 辅助功能服务是否能够取回活动窗口内容的属性;
- settingsActivity 允许用户修改辅助功能的activity组件名称;
也可以运行时在服务的onServiceConnected()方法中动态配置,示例如下:
AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();
serviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; //事件类型
serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;//设置回馈给用户的方式
serviceInfo.packageNames = pachage;
serviceInfo.notificationTimeout = 100; //
setServiceInfo(serviceInfo);
3.在AndroidManifest.xml中进行声明,并引用accessibility_service_config.xml配置文件。
<service
android:name=".TestAccessibilityService1" 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/accessibility_service_config" />
</service>
4.将程序安装并打开开关。
打开开关方式有两种:
- 如果系统中有原生的setting应用,可以直接在无障碍条目中打开。
- 通过adb命令设置相关属性值打开:
settings put secure accessibility_enabled 1
settings put secure enabled_accessibility_services com.cvte.tv.texttospeech/com.cvte.tv.texttospeech.TTSAccessibilityService(有两个服务时用"|"隔开)
无障碍服务的流程分析
总体流程如下:
AccessibilityEvent事件是如何产生和发送的?
- view获取焦点或者被选中时,内部会调用相关的方法初始化AccessibilityEvent的相关信息;
- 在onPopulateAccessibilityEventInternal()方法中设置AccessibilityEvent文本,在onInitializeAccessibilityNodeInfoInternal()方法中设置AccessibilityNodeInfo的文本;
- 调用ViewParent的实现类ViewRootImpl中requestSendAccessibilityEvent()方法;
- AccessibilityManager通过IAccessibilityManager跨进程调用AccessibilityManagerService的sendAccessibilityEvent()方法;
- 最终通过遍历AccessibilityServiceConnection将事件消息分发到各个AccessibilityService服务中。
AccessibilityService是如何接收AccessibilityEvent事件?
- AccessibilityService是一个抽象类,继承于Service,提供两个抽象方法onAccessibilityEvent() 和 onInterrupt();实现了 onBind() 方法,在其中创建了一个IAccessibilityServiceClientWrapper对象。
- 而IAccessibilityServiceClientWrapper继承于IAccessibilityServiceClient.Stub类,可以猜测到,AccessibilityService为一个远程Service,是用跨进程进行通信的。
- 当Client端调用onAccessibilityEvent()方法时,通过HandlerCaller处理消息,并调用CallBacks的onAccessibilityEvent()方法,最后在回调中调用 AccessibilityService.this.onAccessibilityEvent(event)。
AccessibilityService是如何与客户端绑定的?
- AccessibilityManagerService初始化时,注册应用监视器和用户状态改变的广播监听,AccessibilityManagerService是一个系统服务,由SystemService启动;
- 应用监视器广播是用来监听应用状态的改变;
- 以及监听用户切换、用户解锁、用户被移除等状态改变;
- 当状态改变时,调用updateServicesLocked()遍历无障碍服务列表,判断是否启用,进行绑定或解绑;
- AccessibilityServiceConnection.java>>>bindLocked()>>>>mContext.bindServiceAsUser();
如何通过AccessibilityService远程操作view?
图片来自于:https://blog.csdn.net/u010255127/article/details/79184399
无障碍服务的应用
- TalkBack;
- 自动获取短信验证码;
- 自动化测试;
- 外挂:抢红包、抢单;
无障碍服务防御
- 检测 or 禁止相关外挂的辅助模式开启。
a)通过getInstalledAccessibilityServiceList()方法获取所有的无障碍服务,查看这些服务是否有在监控你的应用;
b)通过ContentObserver监听enabled_accessibility_services属性值变化,当有服务开启重复a)步骤检测,防止被恶意软件监控; - Event干扰:通过发送无规律的AccessibilityEvent来干扰恶意软件的逻辑判断。
- onTouch替换onClick,屏蔽点击事件。
- 重写View的findViewsWithText()方法,防止插件通过文本查找到相关的view。
最后
以上就是魁梧楼房为你收集整理的无障碍服务AccessibilityService详解的全部内容,希望文章能够帮你解决无障碍服务AccessibilityService详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复