Appium基础学习之 | AccessibilityService服务

    从Appium扯到了UiAutomator再扯到AccessibilityService服务,好像有点扯远了。而为什么要扯到AccessibilityService服务,是由于在几乎所有资料中都有一个方向就是UiAutomator基于AccessibilityService服务,而到了UiAutomator2.0又基于Instrumentation,有兴趣看到这篇文章的朋友可以注意下,在有UiAutomator涉及的文章中很多都会提到,由于不解,所以需要去理解一下AccessibilityService与Instrumentation,而学习思路是从UiAutomator1.0开始,所以涉及UiAutomator2.0的Instrumentation到后面再说,本文先说AccessibilityService服务。

一、什么是AccessibilityService服务

    辅助功能(AccessibilityService)其实是一个Android系统提供的一种服务,它是继承Service类的。这个服务提供了增强的用户界面,旨在帮助残障人士或者可能暂时无法与设备充分交互的人们。从概念来看懵懵懂懂,接下来看实操。

二、AccessibilityService服务使用

    AccessibilityService服务是android服务,所以要在android项目中使用,前面文章一直在使用Eclipse写代码运行,接下来放弃Eclipse开始在Google Android强烈推荐的Android Studio IDE中写代码运行。

1.新建Android项目

简单的写了几个控件,便于后面的AccessibilityService服务操作,布局文件如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请选择:"/>

        <CheckBox
            android:id="@+id/select"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请输入:"/>

        <EditText
            android:id="@+id/insert"
            android:layout_width="300dp"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <Button
        android:id="@+id/clickButton"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:text="Test"/>


</LinearLayout>

2.新建AccessibilityServiceSample类

创建一个类AccessibilityServiceSample,继承AccessibilityService,然后复写AccessibilityService的几个方法,如下:

public class AccessibilityServiceSample extends AccessibilityService {



    @Override

    public void onServiceConnected(){

        super.onServiceConnected();

    }



    @Override

    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {

      

    }



    @Override

    public void onInterrupt() {



    }

}

(1)onServiceConnected

      系统成功连接到辅助功能服务时调用,可以执行任何一次性设置步骤,包括连接到用户反馈系统服务,如音频管理器或设备振动器。还可以调用setServiceInfo()设置服务配置。

(2)onAccessibilityEvent

      当系统检测到与Accessibility服务指定的事件过滤参数匹配的AccessibilityEvent时调用。这是必须实现的方法,通常需要在该方法中根据AccessibilityEvent作出判断并执行一些处理。

(3)onInterrupt

      当系统想要中断服务提供的反馈时调用,通常是响应用户操作,如将焦点移动到其他控件。

(4)onUnbind与onDestroy

       当系统即将关闭辅助功能服务时调用,可以执行任何一次性关机程序,包括取消分配用户反馈系统服务,例如音频管理器或设备振动器。

3.新建AccessibilityService服务配置文件

在res目录下新建Android Resource Directory文件夹

名字跟类型输入或选择xml,点击OK后在res下面生成xml文件夹。

然后在选中xml文件夹,新建xml文件,自定义名字accessibility_service_config,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

    android:packageNames="com.main"

    android:accessibilityEventTypes="typeAllMask"

    android:accessibilityFlags="flagDefault"

    android:accessibilityFeedbackType="feedbackSpoken"

    android:notificationTimeout="100"

    android:canRetrieveWindowContent="true" />

(1)android:packageNames

指定监听应用程序事件的包名,可指定多个用逗号分隔,不指定则监听所有应用产生的事件。

(2)android:accessibilityEventTypes

服务要监控的事件类型,如通知、窗口改变、点击、焦点改变等等,如果有多个可以用 | 连起来,typeAllMask代表所有类型。

(3)android:accessibilityFeedbackType

服务反馈的方式,如语音、震动等等,feedbackAllMask代表所有类型。

(4)android:notificationTimeout

接受事件的通知超时时间(毫秒)

(5)android:canRetrieveWindowContent

服务能否获取窗口里面的内容,这里必须要设置true,否则后面没办法获取界面内容

这些配置除了在xml里面写之外,还可以在代码中建立一个AccessibilityServiceInfo对象,然后通过setServiceInfo()来设置,下面再说。

4.在AndroidManifest.xml中声明AccessibilityService服务

      打开AndroidManifest.xml文件,在application标签里面生命AccessibilityService服务的使用,代码如下:

<service

    android:name=".AccessibilityServiceSample"
    android:label="@string/app_name"

    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>

(1)android:name

指定AccessibilityService服务的子类,也就是继承了AccessibilityService的类。

(2)android:label

标签表示服务的名字,应用安装后会在手机辅助功能的列表中显示,若没定义标签则不显示。如文中用的是项目名,当安装这个APK后,在手机辅助功能中可以看到该服务。

(3)android:permission

添加系统权限,一定不要漏了这句话,否则android系统会忽略监听

(4)intent-filter标签组添加过滤器,与上面一样,必须添加

(5)meta-data指定声明AccessibilityService服务配置的配置文件位置。

5.在代码中定义AccessibilityService服务配置

      回到AccessibilityServiceSample类中,在上面说可以在代码中通过setServiceInfo()方法设置AccessibilityService服务,就是在onServiceConnected()方法中定义配置,配置的内容与上面xml配置是一样的;2种方法配置任选其一。

@Override

public void onServiceConnected(){

    AccessibilityServiceInfo asinfo = getServiceInfo();

    asinfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;

    asinfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;

    asinfo.notificationTimeout = 100;

    asinfo.packageNames = new String[]{"com.main"};

    setServiceInfo(asinfo);

    super.onServiceConnected();

}

6.onAccessibilityEvent()方法

     回到AccessibilityServiceSample类中,在配置中设置的是监控全部事件,所以当系统监控到事件时,会调用onAccessibilityEvent()方法。

@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {

    AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
    if(nodeInfo != null && "com.main.accessibilityservice".equals(nodeInfo.getPackageName().toString())) {
        List<AccessibilityNodeInfo> nodes = nodeInfo.findAccessibilityNodeInfosByViewId("com.main.accessibilityservice:id/select");
        List<AccessibilityNodeInfo> nodesInsert = nodeInfo.findAccessibilityNodeInfosByViewId("com.main.accessibilityservice:id/insert");
        //回收ondeInfo,避免重复创建
        nodeInfo.recycle();
        //点击操作
        AccessibilityNodeInfo checkinfo = nodes.get(0);
        if(!checkinfo.isChecked()){
            checkinfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            checkinfo.recycle();
        }
        //文本输入内容
        Bundle arguments = new Bundle();
        arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, "测试");
        nodesInsert.get(0).performAction(AccessibilityNodeInfo.ACTION_SET_TEXT,arguments);
    }
}

(1)AccessibilityEvent

服务监控的事件对象,对象包含很多信息,包含监控的事件所在的包名、事件类型、事件发生时间、事件类名等等信息,比如判断当前应用窗口中事件的变化,就可以用AccessibilityEvent事件的TYPE_WINDOW_CONTENT_CHANGED(内容发生改变)、TYPE_WINDOW_STATE_CHANGED(状态发生改变)两种Type类型来完成,它还有非常多的Type,想学习的朋友可以看看源码。

(2)AccessibilityNodeInfo

窗口内容对象,通过getRootInActiveWindow()方法获取主窗口内容

(3)findAccessibilityNodeInfosByViewId

通过id查找对象,返回的是一个List列表;当然AccessibilityNodeInfo对象还提供findAccessibilityNodeInfosByText()方法,根据文本值内容匹配得到对象。

(4)performAction

执行操作,AccessibilityNodeInfo.ACTION_CLICK表示点击操作,如果需要输入内容,需要通过Bundle对象设置输入内容。

(5)recycle

recycle方法表示回收AccessibilityNodeInfo对象

上面代码主要是先判断当前应该包名,如果匹配则进入开始执行点击、输入操作

7.打包Apk安装

    打包过程这里不做叙述,通过加密打包APK后安装在手机设备中,安装完成后,在设置中找到辅助功能

并把服务开启,开启之后,打开监控安装好的APK应用,就会自动进入onAccessibilityEvent方法,执行方法中的代码。这样一个简单的AccessibilityService过程演示完毕。

从过程中可以很清晰的知道AccessibilityService是一种服务监控行为的操作,当进入服务监控到事件后进入onAccessibilityEvent方法运行,达到辅助完成的效果。而现实中也很多应用使用AccessibilityService辅助功能完成的,比如很流行的微信自动抢红包,就是通过AccessibilityService服务监控完成的。虽然整个AccessibilityService简单使用说过了,但是并没有看到有关UiAutomator任何基于AccessibilityService的一点点信息,那UiAutomator基于AccessibilityService的说法成立吗?下一篇继续说。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值