聊到 App 端的自动化,大家能想到的可能是 Appium、UIAutomator2、Airtest 等一系列自动化框架。
Android 系统内置了一个无障碍服务,能完成一系列自动化操作;相比其他自动化框架,无障碍服务可以能完全脱离 PC 端,手机也不需要获取 Root 权限。另外,无障碍服务操作起来更加高效、更加智能。
今天,我们来聊聊无障碍服务,后续一系列项目实战将使用这个方案来实现。
01、概念定义
谷歌官方对无障碍服务的定义如下:无障碍服务是一个为残疾人或可能暂时无法与设备完全互动的人提供用户界面扩展功能的应用程序无障碍服务提供了一个服务,方便我们操作一些应用完成一系列定义好的操作。
很多手机厂商内置的抢红包提醒功能就是利用 Android 系统提供的无障碍服务实现的。
02、使用方法
要开启无障碍服务,只需要 5 个简单的步骤即可实现。
无障碍服务配置文件可以配置无障碍服务监听的应用和事件。
其中,packageNames指定监听的应用程序对象的应用包名;accessibilityEventTypes 指定要监听的事件类型;description 为无障碍服务的描述信息;notificationTimeout 是事件发送的时间间隔,一般默认为100毫秒。
比如,微信的typeWindowStateChanged、typeWindowContentChanged 两个事件,事件发送时间为 100毫秒。
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:accessibilityFeedbackType="feedbackAllMask"
android:canRetrieveWindowContent="true"
android:description="@string/service_wechat_description"
android:notificationTimeout="100"
android:packageNames="com.tencent.mm" />
然后,新建一个无障碍服务的子类,重写无障碍服务内的 3 个方法。
public class WeChatService extends AccessibilityService{
@Override
public void onAccessibilityEvent(AccessibilityEvent event)
{
//监听事件
}
@Override
public void onInterrupt()
{
//服务断开
}
@Override
protected void onServiceConnected()
{
super.onServiceConnected();
//服务开启
}
}
onAccessibilityEvent(event)可以拿到对拿到目标应用配置文件中配置的事件类型,针对每一个事件类型,可以编写对应的应用逻辑。
onServiceConnected()方法在无障碍服务被开启的同时,会被触发。
onInterrupt()方法在服务被终端的时候触发。
接着,需要在项目的配置文件 AndroidManifest.xml 中配置服务,并指定上面编写的配置文件。
<service
android:name=".WeChatService"
android:enabled="true"
android:exported="true"
android:label="@string/service_wechat_label"
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/config_accessibility" />
</service>
最关键的是编写事件的逻辑,根据配置文件中指定的事件类型和页面元素,包含类型、包名、顶部 Activity 来编写响应的逻辑。
比如,要实现抢红包的功能,就需要对页面更新和内容更新两个事件进行处理,如果页面元素中出现了红包的标识,就获取到红包所在的元素,执行点击操作,就可以实现抢红包的这一操作。
最后,就是打开无障碍服务。
在布局文件中放一个按钮,判断无障碍服务是否打开,如果没有打开,就跳到无障碍服务设置界面,手动打开即可。
/**
* 检查当前无障碍服务是否开启
*
* @param serviceName 服务名称
* @return 服务是否启用
*/
@SuppressLint("LongLogTag")
public boolean checkAccessibilityEnabled(String serviceName)
{
List<AccessibilityServiceInfo> accessibilityServices =
mAccessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC);
for (AccessibilityServiceInfo info : accessibilityServices)
{
Log.e("checkAccessibilityEnabled", info.getId());
if (info.getId().equals(serviceName))
{
return true;
}
}
return false;
}
03、补充一下
上面的步骤介绍了使用无障碍服务的完整流程,基于此,我们使用一部手机,就能完成应用内大部分的自动化操作。
后续将利用一系列项目,带大家一步步地进行学习和项目实战。