本文正在参加「金石方案 . 分割6万现金大奖」

「李跳跳」是什么?

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

一款用于越过开屏广告的东西类运用。

其核心的原理,是借助Android体系上供给的无妨碍功用,检测出当前界面上越过按钮的位置,并主动帮咱们完结点击的动作。

「无妨碍」功用是什么?

解释这个概念之前,咱们先来看几张图:

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

以上这些都是在公园、地铁等的公共场所里常见的设施,意图是为了保障残疾人、老年人及其他行动不便者能安全、便利地通行,体现的是关于社会少数群体的关怀和尊重。

无妨碍功用的规划初衷也是如此,同样是为了照顾到部分视力/听力受损、有认知妨碍或无法完结精细动作的残障人士,使他们也能够和其他正常人一样,无妨碍地运用手机运用来完结日常的交流、学习和工作

除此以外,无妨碍功用还能够补偿运用在某些运用场景上的限制,比方在烹饪的一起运用菜谱类的运用,有了无妨碍功用的辅佐,咱们就能够运用语音指令而非触控手势来控制运用了。

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

Android体系上供给的无妨碍功用,实际可分为两个不同层面上的内容:

规划层面上,它要求运用界面上的元素:

  • 控件尺度尽或许大,以便利用户点按

  • 色彩比照度尽或许高,以便利用户查看

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

  • 尽或许包括能描绘控件实际用途的阐明文字

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

操作层面上,它要求运用内供给的服务:

  • 尽或许为用户的每个操作供给及时、有用的反应

  • 尽或许简化操作的过程,或帮忙用户完结复杂操作

后者首要依靠渠道级的「无妨碍服务」(AccessibilityService)来完成。

「无妨碍服务」能做什么?

Android体系供给了许多规范的无妨碍服务完成,比方TalkBack这项服务,其供给了与屏幕交互时的实时语音反应,关于盲人和视力低弱人士非常实用。

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

一起Android也答应开发者创立和分发自己的服务,以增强与用户的互动作用,打造运用范围更广的功用。

详细展开讲的话,自界说的无妨碍服务通常包括对以下几个事项的处理:

收集信息

这儿收集的首要是与界面交互相关的信息,包括所操作目标的类型、其包括的描绘性文字以及其他详细信息。

咱们知道,Android运用所采用的界面布局,是根据ViewViewGroup目标、以树状结构来进行构建的视图层级。

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

Android体系正是根据此视图层级结构编写的无妨碍工作,也即,它不只会回来用户当前所交互的控件自身,还会回来包括此控件的父视图,以及此控件所包括的一系列子视图,这部分额外的信息统称为控件的上下文信息

上下文信息关于用户理解其所交互控件的意义至关重要。

以一个简略的复选框为例,关于一个有视力妨碍的用户来说,假如无妨碍服务仅仅反应“是否选中”,而未能阐明“选中的是什么内容”,用户就会感到很困惑。

有了完好的上下文信息,无妨碍服务就能够为用户供给更加实用和有用的反应。

对工作做出呼应

这部分比较简略,通常便是确定无妨碍工作的类型,并从触发此工作的视图节点中提取有用的文字描绘,以文字转语音或振荡的办法反应给用户。

为用户履行操作

无妨碍服务能够代替用户履行的操作,通过数个体系版别的迭代扩展,现在已经支撑多达数十种,包括但不限于点击、长按、复制、粘贴、翻滚、翻页等。

能够说,基本上,只要是Android渠道上的规范UI控件(如TextView、RecyclerView、ViewPager等)内可支撑的操作,都有对应的无妨碍操作类型供给。

并且,这类操作不只能够在运用内进行,还能够在体系全局进行,比方回到主屏幕、按“回来”按钮,以及翻开最近运用的运用列表等,因而能够极大地简化用户与运用、体系之间的互动。

所以,说了这么多,「李跳跳」的「越过开屏广告」功用到底是怎样完成的呢?

越过开屏广告是怎样完成的?

其实,假如你能看到这儿,此刻你的脑海里应该就已经有了大致的思路,下面,就让咱们用代码来实际还原一下:

创立无妨碍服务

首要咱们要做的,便是创立一个扩展自AccessibilityService的类。

class MyAccessibilityService : AccessibilityService() {
...
}

因为无妨碍服务本质上便是一个服务(Service),因而必须在AndroidManife运用清单文件中包括特定的声明。

在service元素的声明中,咱们还必须增加一个intent过滤器,告知体系这是一个无妨碍服务。

此外,咱们还需求增加 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>

装备无妨碍服务

装备的意图是为了告知体系,咱们的无妨碍服务运转的办法和机遇、呼应的工作类型、是针对特定的运用还是一切的运用以及采用的反应类型等。

装备的办法有代码办法和XML文件办法两种,这儿咱们首要介绍后者。

首要,咱们需求在res/xml目录下创立一个名为serviceconfig(命名可随意)的XML文件,其间的每一个键值对即表明一个装备选项,详细每一个装备选项的意义咱们留到后边再介绍:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:canRetrieveWindowContent="true"
    />

随后,为了保证引用到该文件,咱们需求在上面的服务声明中增加一个指向该XML文件的符号:

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

注册无妨碍工作

这一步的作用便是确立咱们的无妨碍服务要处理的工作来自哪个运用的哪些工作类型,与此关联的几个装备选项便是:

  • android:packageNames(软件包称号):指定可接纳的无妨碍工作的运用来历。假如有多个运用需求指定,可用逗号进行分隔。而假如未指定,则默认接纳来自一切运用的无妨碍工作。

  • android:accessibilityEventTypes(工作类型):指定可接纳的无妨碍工作的工作类型。例如,accessibilityEventTypes=”typeViewClicked|typeViewFocused”就表明可接纳点击和获取焦点这两种工作类型,多个工作类型之间运用|进行分隔,typeAllMask则表明接纳一切类型的工作。

此外,为了保证能获取无妨碍工作来历控件的视图层次结构(即获取其父视图和子视图),咱们还需增加canRetrieveWindowContent特点,并将其设为true,以请求相应的拜访权限。

请求无妨碍服务权限

只有当体系绑定到咱们界说的无妨碍服务,咱们的服务才能正常运转起来,为此,咱们需求跳转到体系的无妨碍设置界面,敞开咱们装置的无妨碍服务,代码如下:

startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))

华为P30 pro为例,以上代码所跳转到的界面,对应的操作路径是「设置-辅佐功用-无妨碍」,随后,咱们就能够从已装置的服务里找到咱们自己的服务,然后点击敞开按钮,咱们的服务就会运转起来。

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

重载无妨碍服务办法

除了常规的Service类办法外,无妨碍服务还额外供给了2个必须重载的办法,分别是:

  • onAccessibilityEvent():当体系检测到与咱们前面的装备选项相匹配的工作时,就会回调此办法,工作将以AccessibilityEvent类目标的办法供给。随后咱们就能够解析该目标,并履行相应的处理。这个办法或许会在服务的整个生命周期内被调用多次。

  • onInterrupt():当体系要中止咱们的服务正在供给的反应时(通常是在控件焦点转移时),就会回调此办法。

获取工作详细信息

开头咱们就讲了,「李跳跳」越过开屏广告实际上就2步完成:

  1. 检测「越过」按钮的位置
  2. 主动完结「点击」的动作

关于过程1,咱们要做的工作便是,在接纳到无妨碍工作后,运用getSource()从工作中检索出AccessibilityNodeInfo目标, 通过AccessibilityNodeInfo目标,咱们能够阅读当前界面的视图层级结构,找到包括“越过”字样文本的工作来历节点。

至于过程2就很简略了,直接调用performAction(ACTION_CLICK)为用户履行点击操作即可。

完好代码如下:

class MyAccessibilityService : AccessibilityService() {
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        val source = event.source ?: return
        for (i in 0 until source.childCount) {
            if (source.getChild(i)?.text?.contains("越过") == true) {
                source.getChild(i).performAction(ACTION_CLICK)
            }
        }
        source.recycle()
    }
    override fun onInterrupt() {
    }
}

作用演示

能够看到,比照前一个未启用越过开屏广告功用的网易云版别,后一个版别会在开屏广告显示的瞬间,就帮咱们主动点击了越过按钮,以达到越过开屏广告的作用。

还想说点什么

好了,到这儿咱们就完结了一个“简易版”的李跳跳了,之所以说是“简易版”,是因为现在的李跳跳早已不限于越过广告这一首要功用了,但大体上还是根据无妨碍功用进行扩展的。

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

这也让我不得不慨叹,能力是有限的,但创意能够是无限的。Android开发团队或许也从未想到,无妨碍功用居然还能够用来做这么多工作。实践之后,我也不得不对李跳跳开发者的创意拍手叫绝。

但另一方面,我也衍生出一种忧虑,至于原因,显而易见,无妨碍功用在解锁了相应的权限之后,其所能掌握的关于手机的控制权是相当可怕的

能读取屏幕内容,就或许盗取隐私;能控制用户行为,就或许违法犯罪。况且服务自身的特点便是在后台长期运作,而不需求供给界面的。假如还答应这类运用在后台持续保活的话,真不敢幻想它会在你意想不到的时候做出什么出格的工作。

当然我相信「李跳跳」的开发者的初心是纯粹的,毕竟多省下几秒看无聊广告的时间,就多几秒能够去做更有意义的工作,我仅仅表达对这种过度权力自身的忧虑,毕竟就像罗翔老师说的:

网络热传App鉴定 |「李跳跳」里用到的无障碍权限是什么?

同作为开发者,我佩服「李跳跳」的创意,但我敬畏这种权力。

少侠,请留步!若本文对你有所帮助或启发,还请:

  1. 点赞,让更多的人能看到!
  2. 保藏⭐️,好文值得重复品味!
  3. 关注➕,不错失每一次更文!

===> 技能号:「星际码仔」

你的支撑是我继续创造的动力,感谢!