本文章主要内容为如何在PC或服务器上为指定android程序模拟随机点击并对其进行截图。
主要解决的问题是获取android设备上当前时间所显示的内容,截图后保存到本地(服务器端),而非android设备上。
主要利用的工具为chimpchat.jar与ddmlib.jar两个jar包,这两个jar包包含在android sdk内,一般在sdk/tools/lib/下,这两个jar包所完成的工作不过是封装了一些协议及一些常用操作,如操纵设备点击、拖动等,也包含了将命令(cmd)在android设备上执行的功能。
核心代码如下,代码展示了对一个应用程序进行随机点击并截图保存,里边用到了monkey自动化测试工具来完成随机点击事件:
ChimpChat c = ChimpChat.getInstance(); //等待设备连接 IChimpDevice paramIChimpDevice = c.waitForConnection(); //截图 paramIChimpDevice.takeSnapshot(); //cmd内容为执行monkey命令 paramIChimpDevice.shell(cmd, 5 * 1000 * 60);
具体代码如下:
AutoApp.java
package com.surfilter.autoapp;
import com.android.chimpchat.ChimpChat;
import com.android.chimpchat.core.IChimpDevice;
import com.surfilter.autoapp.action.MonkeyAction;
import com.surfilter.autoapp.screenshot.ScreenShot;
/**
* @author liu
*
*/
public class AutoApp {
private static long DEVICE_CONNECTION_TIMEOUT = 10000l;
private static int MONKEY_WAIT_TIMEOUT = 1000 * 5 * 60;
public static void main(String[] args) {
String appName = "woxiu";
String deviceId = "android";
String packageName = "com.wole56.ishow";
String path = "E:\\snapshot\\"+ appName +"\\";
//阻塞执行,执行过程中设备不能做其他事情
runApp(deviceId, path, packageName, appName);
}
/**
* 在指定设备上运行程序并随机点击后截图
* @param deviceId
* @param path
* @param monkeyWaitTimeout
* @param packageName
* @param appName
*/
public static void runApp(String deviceId, String path, String packageName, String appName){
ChimpChat c = ChimpChat.getInstance();
final IChimpDevice paramIChimpDevice = c.waitForConnection(/*DEVICE_CONNECTION_TIMEOUT, deviceId*/);
final ScreenShot ss = new ScreenShot(paramIChimpDevice, path, appName);
//回调中停止截图,并且关闭android设备上的命令监听服务
Callback callback = new Callback() {
@Override
public void callback() {
System.out.println("over...");
ss.endTakeShot();
paramIChimpDevice.dispose();
}
};
MonkeyAction ma = new MonkeyAction(paramIChimpDevice, packageName, MONKEY_WAIT_TIMEOUT, callback);
ss.beginTakeShot();
ma.action();
}
}
MonkeyAction.java
package com.surfilter.autoapp.action;
import com.android.chimpchat.core.IChimpDevice;
import com.surfilter.autoapp.Callback;
public class MonkeyAction {
private static String MONKEY_CMD = "monkey";
private IChimpDevice paramIChimpDevice;
private String packageName;
private int shellWaitTimestamp = 5 * 1000 * 60;
private long seed = 10000;
private long executeTimes = 50000;
private long executeSepratTime = 100;
private boolean ignoreInfos = true;
private Callback callback;
public MonkeyAction(IChimpDevice paramIChimpDevice, String packageName, int shellWaitTimestamp, Callback callback) {
this.paramIChimpDevice = paramIChimpDevice;
this.packageName = packageName;
this.callback = callback;
this.shellWaitTimestamp = shellWaitTimestamp;
}
/**
* 开始执行Monkey
* @return
*/
public boolean action(){
try{
paramIChimpDevice.shell(getExecuteCmd(), shellWaitTimestamp);
clean();
if(callback != null){
callback.callback();
}
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
private void clean(){
//TODO:需要清理monkey进程
//paramIChimpDevice.shell("ps |grep monkey", 3000);
}
private String getExecuteCmd() {
StringBuilder sb = new StringBuilder();
sb.append(MONKEY_CMD);
sb.append(" -v ");
sb.append(" -p ");
sb.append(packageName);
sb.append(" -s ");
sb.append(seed);
if(executeSepratTime != 0){
sb.append(" --throttle ");
sb.append(executeSepratTime);
}
if(ignoreInfos){
sb.append(" --ignore-crashes ");
sb.append(" --ignore-timeouts ");
sb.append(" --ignore-security-exceptions ");
sb.append(" --kill-process-after-error ");
}
sb.append(executeTimes);
return sb.toString();
}
public static void main(String[] args) {
System.out.println(new MonkeyAction(null, "com.tencent.qq", 5 * 1000, null).getExecuteCmd());
}
}
ScreenShot.java
package com.surfilter.autoapp.screenshot;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
public class ScreenShot {
private IChimpDevice paramIChimpDevice;
private String path;
private String fileNamePrefix;
private int fileCount = 0;
private String fileType = "png";
public ScreenShot(IChimpDevice paramIChimpDevice, String path,
String fileNamePrefix) {
this.paramIChimpDevice = paramIChimpDevice;
this.path = path;
this.fileNamePrefix = fileNamePrefix;
}
private boolean isBegined = false;
private boolean isStoped = false;
/**
* 开始截图
* @return
*/
public boolean beginTakeShot(){
if(!isBegined){
isBegined = true;
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try{
if(!isStoped){
takeShot();
}
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}).start();
}else{
System.out.println("已经开始截图了..");
}
return true;
}
/**
* 停止截图
* @return
*/
public boolean endTakeShot(){
isStoped = true;
return isStoped;
}
private boolean takeShot() {
boolean success = false;
IChimpImage chimpImage = paramIChimpDevice.takeSnapshot();
if(chimpImage == null){
return success;
}
if (needSave(chimpImage)) {
success = chimpImage.writeToFile(genFileName(), fileType);
if (success) {
fileCount++;
}
}
return success;
}
private String genFileName() {
return path + "/" + fileNamePrefix + "_" + fileCount + "." + fileType;
}
private IChimpImage lastImage;
private boolean needSave(IChimpImage chimpImage) {
boolean flag = false;
if(lastImage != null){
flag = chimpImage.sameAs(lastImage, 0.8);
lastImage = chimpImage;
}else{
lastImage = chimpImage;
}
return !flag;
}
}
Callback.java
package com.surfilter.autoapp;
public interface Callback{
public void callback();
}

你好,能实现更复杂的功能吗?比如截长图,模拟用户做点击、输入内容等操作
方便的话加QQ,联系一下,我QQ:404230497