近两年,短视频出现了井喷式的发展。快手、快手、微视、火山视频等我们比较熟悉。看短视频已经成为年轻人的一种习惯,每天空闲的时候都会拿出手机。刷刷刷,打发无聊时间。其实快手和快手都推出了极速版,还可以一边娱乐一边刷视频赚钱,但纯属娱乐,一天没多少钱。
但是作为测试人员,有没有办法让视频自动闪烁呢?方法是有的,今天我们就来开发一款可以自动刷新短视频的软件。如果我们学习了它,我们可以在其他可以赚钱的应用程序中使用它。
我们首先能想到的就是开发一个自动化脚本,使用android adb命令模拟滑动,命令是adb shell输入swipe,然后设置一个循环等待固定时间滑动一次,使用windows批处理或者用python开发一个脚本就可以了。但缺点是很有序,需要一直开着电脑,不能随时随地刷,没意义。
另一种可能想到的方法是开发一个android app应用,然后在应用中使用Android Runtime方法调用adb swipe命令,比如Runtime.getRuntime().exec("input swipe"),其实等你试一下就会成功,因为在应用中调用adb命令需要root权限,而我们自己使用的普通手机是无法使用的。
还有第三种方法是android无障碍服务AccessibilityService。辅助服务的初衷是为无法与界面交互的残障用户提供一些用户操作的辅助,如点击、返回、长按、获取屏幕信息等。后来开发者又找到了另一种方式来开发一些插件,制作一些监控第三方应用的插件。
我们不会解释如何使用无障碍服务,也不会在打开应用程序时引导用户打开辅助服务。这些都可以在网上找到,只需要移植即可。下面说一下辅助服务中的滑动、双击、跳过广告的设计。首先是关于滑动的实现,主要是使用AccessibilityService在android7.0上新增的dispatchGesture和GestureDescription类。两个类的介绍如下,网上也有。首先是dispatchGesture方法的解释:
boolean dispatchGesture (GestureDescription gesture, AccessibilityService.GestureResultCallback callback, Handler handler)
这个方法有三个参数: 参数 GestureDescription:翻译的是手势的描述。如果要模拟手势,首先要描述你的腰部模拟的手势;参数GestureResultCallback:翻译为手势的回调,手势模拟的结果在手势模拟执行后回调;参数处理程序:在大多数情况下,如果我们不需要它,我们可以将其传递为空。一般我们关注一下GestureDescription的参数就够了。让我们关注这个参数:构建手势描述的关键代码:
GestureDescription.StrokeDescription(Path path, long startTime, long duration);
例如:
GestureDescription.Builder builder = GestureDescription.Builder();
GestureDescription gestureDescription = builder
.addStroke(GestureDescription.StrokeDescription(path, 100, 400)).build();
参数介绍如下: 参数path:描边路径,即滑动路径,可以通过path.moveTo和path.lineTo实现;参数startTime:时间(以毫秒为单位),从手势开始到笔划开始的时间,非负数;参数duration:笔划通过路径的持续时间(以毫秒为单位),非负数;
介绍完上面的基础知识,我们来看看滑动代码需要如何开发,见下图:
private void mockSwipe(){
final Path path = new Path();
path.moveTo(X, Y); //滑动的起始位置,例如屏幕的中心点X、Y
path.lineTo(X, 0); //需要滑动的位置,如从中心点滑到屏幕的顶部
GestureDescription.Builder builder = new GestureDescription.Builder();
GestureDescription gestureDescription = builder.addStroke(
new GestureDescription.StrokeDescription(path, 100, 400)
).build(); //移动到中心点,100ms后开始滑动,滑动的时间持续400ms,可以调整
dispatchGesture(gestureDescription, new GestureResultCallback() {
//如果滑动成功,会回调如下函数,可以在下面记录是否滑动成功,滑动成功或失败都要关闭该路径笔画
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
Log.d(TAG, "swipe success.");
path.close();
}
public void onCancelled(GestureDescription gestureDescription) {
super.onCancelled(gestureDescription);
Log.d(TAG, " swipe fail.");
path.close();
}
}, null); //handler为空即可
}
然后实现了滑动,如何实现双击like之类的,也许你有想过,没错,就是通过构造路径来实现的,你只需要设置相同的起点和终点,而不需要lineTo的坐标和 moveTo 是一样的。,双击实现如下:
private void mockDoubleClick(){
final Path path = new Path();
path.moveTo((int)(X/2), (int)(Y/2)); //X和Y是需要双击的按钮坐标
GestureDescription.Builder builder = new GestureDescription.Builder();
GestureDescription gestureDescription = builder.addStroke(
new GestureDescription.StrokeDescription(path, 0, 100)).build();
dispatchGesture(gestureDescription, new GestureResultCallback() {
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
Path path2 = new Path();
path2.moveTo((int)(X/2), (int)(Y/2));
//以下代码是完成第二个手势操作
GestureDescription.Builder builder2 = new GestureDescription.Builder();
GestureDescription gestureDescription2 = builder2.addStroke(
new GestureDescription.StrokeDescription(path2, 0, 100)).build();
AccessibilityServiceTest.this.dispatchGesture(gestureDescription2, null, null);
Log.d(TAG, "double click finish.");
path.close();
path2.close();
}
public void onCancelled(GestureDescription gestureDescription) {
super.onCancelled(gestureDescription);
Log.d(TAG, "scroll cancell.");
}
}, null);
}
至于查找控件,可以使用辅助服务的AccessibilityService的AccessibilityNodeInfo和findAccessibilityNodeInfosByText。具体操作如下:
rootInfo =AccessibilityServiceTest.this.getRootInActiveWindow();
List
listInfo = rootInfo.findAccessibilityNodeInfosByText("查找文本");
注意:未提及应用程序的其他开发方面。例如添加辅助服务和指令,请看原文中的AndroidManifest.xml和simulatekey.xml(辅助服务的设置)文件。