前言:工信部发布的互联网应用适老化及无障碍改造的通知,app 需要进行改造,以提高老年人或者视障人士在使用 app 过程的便捷性,改造的内容包括但不限于

1、UI 界面更简单、整洁(界面元素不能过于复杂,字体字号需要偏大、清晰)

2、页面焦点导航的适配

3、页面元素需要适配 TalkBack 朗读

4、搭建无障碍服务 service

关于界面文字字号大小的选择的,我前面发过文章介绍过方案,今天主要讲讲 android 中 Accessibility 相关使用以及其他一些简单的改造。

一、给控件加上 contentDescription 属性和正确的朗读文案。

(1)对于 TextView / Button,TalkBack 会读出设置的 text 属性的文本,一般情况不需要特殊适配

(2)对于 EditText ,TalkBack 会读 hint 属性设置的文字,输入内容后会播报输入后的问题

(3)对于其他没有 text 属性的控件

1、通过 layout 文件里面设置 contentDescription 属性设置文本

2、通过代码中调用 view.setContentDescription() 方法设置文本

    <ImageViewandroid:layout_width="@dimen/dp_190"android:layout_height="@dimen/dp_190"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:src="@drawable/bg_login_watermark"android:contentDescription="@string/love_version_read_Img_Water_mark"/>
iv_back.setContentDescription(getString(R.string.love_version_read_Img_Back));

二、启用焦点导航

在使用 TalkBack 测试的过程中,发现有些比较复杂的布局内容子控件点击不到,因此也无法播报,这就需要我们对页面的焦点视图做好控制。

(1)如果我们需要某个控件是可以在 TalkBack 模式下可点击并播报的话,需要给控件设置 android:focusable = "true",或者在代码中调用 setFocusable()。否则的话焦点会在整个父布局,导致某个区域块点击会顺序播报整块区域的内容。

(2)设置焦点顺序。

通过 android:nextFocusDown, android:nextFocusLeft, android:nextFocusRight, android:nextFocusUp 或者运行时通过 setNextFocusDownId(), setNextFocusrightId() 等方法动态控制用户界面组件的聚焦顺序。以确保用户在使用手势、虚拟键导航时可以有较好的体验。

(3)talkback 开启不获取焦点。

如果你希望该区域(ViewGroup、View)不播报,通过下面代码来设置。

<View
android:impoartantForAccessibility="no"/> 

三、给控件加上正确的播报类型

一般的,我们需要让视障人士清楚当前点击的区域是什么,比如我们的按钮、图片等等,开启 talkback 的情况下,通过设置类型来让系统在控件获取焦点时播报。

例如:下面的设置,系统将会播报“按钮,(设置好的 contentDescription)”

ViewCompat.setAccessibilityDelegate(tv_url, new AccessibilityDelegateCompat(){@Overridepublic void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {super.onInitializeAccessibilityNodeInfo(host, info);info.setClassName(Button.class.getName());}});

四、拦截自定义视图的播报。

项目中,难免会用到一些自定义的组件,比如 banner、手势滑动组件等等。例如在项目中我自已写的一个画廊效果的滑动窗,在开启 talkback 模式之后,滑动会播报 “多视图页面,第一项,第二项”之类的,我们当然不希望用户听到这些,即便是在加了 contentDescription 之后也依旧会存在,这个时候,通过重写 onRequestSendAccessibility() 方法,你可以直接 return false,即不处理该事件,就不会播报上述的“多视图页面”。

@Overridepublic boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {return false;}

五、拦截页面的播报。

开启 talkback 模式下,在 Activity 或者 Fragment中,进入一个新的页面时,往往会触发系统一些播报。我遇到的情况是,在首页有广告 banner 的情况下,进入首页系统就会播报“第 2000 项目,共 两千零几项”这种。

解决方法:

@Overridepublic boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {event.getText().add("");return super.dispatchPopulateAccessibilityEvent(event);}

六、主动播报。

有些场景下,需要对用户的滑动做出反馈,比如 banner,滑动选择窗口。当用户滑动到某一项,但是还未点击的时候,我们可以做出反馈,通过 announceForAccessibility() 方法 及时反馈当前的选中项。

tv_url.announceForAccessibility("您当前选中的是。。。");

七、判断当前是否开启 talkback 模式。

有些场景,需要判断手机是否开启 talkback 模式,以此来进行一些特殊的逻辑处理。比如一些app会有人脸识别、身份证识别的功能。在talkback 模式下,对当前的识别状态进行播报反馈,提升用户的体验。比如人脸识别,脸太靠前,或者不居中等情况,一般都只有文字提示,我们判断系统是否开启 talkback,将文字提示进行播报。

(1)通过 AccessibilityManager 的 isEnabled() 方法。

AccessibilityManager accessibilityManager;
accessibilityManager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
boolean isTalkBackEnabled = accessibilityManager.isEnabled();

但是这个方法有个问题,就是不够准确,测试的时候发现,有的手机单用这个方法会有误判的情况,就是手机明明没有开启 talkback,但还是返回了 true。后面了解到是有些 app ,会开启相关的 AccessibilityService ,比如爱奇艺,所以在安装了爱奇艺app的手机,isTalkBackEnabled 就返回了 true。影响了我们的判断结果。所以我们需要再加一个判断。

(2)直接上代码了

private static boolean isTalkBackEnable(Context context) {Intent screenReaderIntent = new Intent(SCREEN_READER_INTENT_ACTION);screenReaderIntent.addCategory(SCREEN_READER_INTENT_CATEGORY);List<ResolveInfo> screenReaders = context.getPackageManager().queryIntentServices(screenReaderIntent, 0);if (screenReaders == null || screenReaders.size() <= 0) {return false;}boolean hasActiveScreenReader = false;if (Build.VERSION.SDK_INT <= 15) {ContentResolver cr = context.getContentResolver();Cursor cursor = null;int status = 0;for (ResolveInfo screenReader : screenReaders) {cursor = cr.query(Uri.parse("content://" + screenReader.serviceInfo.packageName+ ".providers.StatusProvider"), null, null, null, null);if (cursor != null && cursor.moveToFirst()) { status = cursor.getInt(0);cursor.close();// 状态1为开启状态,直接返回true即可if (status == 1) {return true;}}}} else if (Build.VERSION.SDK_INT >= 26) {// 高版本可以直接判断服务是否处于开启状态for (ResolveInfo screenReader : screenReaders) {hasActiveScreenReader |= isAccessibilitySettingsOn(context, screenReader.serviceInfo.packageName + "/" + screenReader.serviceInfo.name);}} else {// 判断正在运行的Service里有没有上述存在的ServiceList<String> runningServices = new ArrayList<String>();android.app.ActivityManager manager = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);for (android.app.ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {runningServices.add(service.service.getPackageName());}for (ResolveInfo screenReader : screenReaders) {if (runningServices.contains(screenReader.serviceInfo.packageName)) {hasActiveScreenReader |= true;}}}return hasActiveScreenReader;}

以上两点同时使用就可以准确判断是否开启 talkback 了。第二点是参考下面这篇博客的,感谢老哥哈,一开始我只用了第一种,在测试机就没问题,在自己手机就不行,后面看完才知道是我手机安装了爱奇艺的原因。

参考的博客地址:Android完美判断是否开启无障碍服务功能 - 简书

这是一条分隔线

本次 APP 适老化改造用到的内容大概就这么多,后面如果有继续优化再接着补充。

简单使用 Accessibility 及 Android 适配 TalkBack,实现适老化和无障碍相关推荐

  1. Android端适老化与无障碍改造

    文章目录 第一部分 背景 1.1 社会现状 1.2 改造标准 1.3 市场案例 第二部分 技术剖析 2.1 适老化 2.1.1 字体大小适配 2.1.2 扩大点击范围 2.1.3 屏幕尺寸适配解决方案 ...

  2. 【Android】Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法

    Android适配器之ArrayAdapter.SimpleAdapter和BaseAdapter的简单用法与有用代码片段 ArrayAdapter.SimpleAdapter和BaseAdapter ...

  3. android ui布局适配,Android适配全面总结(一)----屏幕适配

    前言 Android适配是一个老生常谈的问题,很多程序员觉得很恶心,不愿意做适配,但是又不得不做.然后老板说,这位兄弟,做好了,今天晚饭给你加个鸡腿,然后程序员开始找各种资料,忙活起来了,最终在苦逼的 ...

  4. json 微信小程序 筛选_GitHub - zhengyangkang/sl-filter: uni -app 一款使用简单的筛选组件,适配app、微信小程序、H5。...

    sl-filter 筛选 筛选组件,组件名:sl-filter dcloud插件市场地址 sl-filter 简介 一款使用简单的筛选组件,适配app.微信小程序.H5. 感谢分享 效果图 并列菜单 ...

  5. Android适配虚拟按键-亲测华为小米手机有效

    Android适配虚拟按键-亲测华为小米手机有效 应用上传华为应用市场,结果被拒,原因是真人测试手机带虚拟按键,结果导致虚拟按键和屏幕某点击事件冲突,一点击就会退出到手机主页.废话不多说,直接上代码. ...

  6. Android适配全面总结(一)----屏幕适配

    版权声明:本文为博主原创文章(部分引用他人博文,已加上引用说明),未经博主允许不得转载.https://www.jianshu.com/p/7aa34434ad4d 转载请标明出处: https:// ...

  7. 谈一谈Android适配(从蓝湖切图模糊问题说开去)

    最近在新的项目画UI的时候,从蓝湖导出切图后,发现显示很模糊.最后发现是蓝湖设置问题,没有正确计算不同dpi目录下的图片像素值.适配问题看起来很简单,但是很多细节却很容易被忽略,而且网上也有一些文章讲 ...

  8. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

  9. Android 适配(一)

    一.Android适配基础参数 1.常见分辨率(px) oppx 2340x1080 oppR15 2280x1080 oppor11sp 2160*1080 1080*1920 (主流屏幕16:9) ...

最新文章

  1. 最全技术剖析:百度视觉团队获世界最大规模目标检测竞赛冠军
  2. ​std::multimap
  3. linux隔一级目录找文件,linux查看文件和子目录
  4. 把树分成森林 matlab,20170106RF_Matlab 随机森林指的是利用多棵树对样本进行训练并预测的一种分类器,包括两个方面:数据的随 269万源代码下载- www.pudn.com...
  5. python组件化软件github_GitHub - 872409/wepy: 小程序组件化开发框架
  6. python释放变量内存_python解释器安装,运行python程序的方式及程序运行的步骤,变量与自动的内存管理...
  7. Ubuntu安装Curl的方法
  8. Lesson 3 Part 1 Locally weighted regression
  9. superoneclick 2.2_总投资2.2亿!又一年产10万吨水性乳液项目开工
  10. 父html向子html传递参数,子父组件之间传值.html
  11. cadence软件下载linux,Red Hat Linux 9.0下安装Cadence IC5.0
  12. Powertoys windows 10第三方桌面分块(分区)工具
  13. 项目管理基础:9.项目人力资源管理
  14. 浅谈在线IDE的搭建,配置,体验
  15. 关于英语论文范文参考步骤的详细介绍
  16. 第三篇 ME909s-821设备描述符分析
  17. oracle exclude table,EXPDP/IMPDP:关于EXCLUDE参数
  18. Thinkpad 禁用触摸板
  19. 使用Stream distinct()去重失效问题
  20. 面试宝典(一)之程序员必备面试软技能

热门文章

  1. 看“废物”如何重生,看“闲鱼”如何翻身
  2. 软件工程SWEBOK所包含的10个领域以及每个领域所做的事情
  3. CDN怎么用?有哪些优势呢?如何挑选CDN服务商?
  4. 浅谈linux的几种重启命令,linux用命令重启的两种方法(Linux重启关机命令经验之谈)...
  5. [软件评测第八期]看图猜成语
  6. 【领扣leetcode数据库】176.第二高的薪水
  7. 计算机知识不如别人,一个计算机从业人员的心声——有时候“授人以渔不如授之以鱼”...
  8. Vidahouse独创“DNA技术”颠覆你的设计观
  9. char int 取值范围
  10. 2022年测试岗最新自动化测试面试题整理,干货满满