论文写完,感受头脑很久没被灵感刺激了,前些天室友介绍了个小游戏,我忽然来了灵感能够写的简单的android 程序实现自动运行。主要的过会为三步:php
1,Android 屏幕的获取。由于安全的缘由,过程比较麻烦,我目前采用的是开启用户调试模式,利用adb脚本反复循环截图。java
2,图像分析。这部分代码中有体现,过程比较简单。android
3,模拟Click。代码中已经体,,我采用了一种最简单的方法,代码将在下面作详细分析。shell
先上个图,一口气跑到183分:安全
分析图片的代码以下,具体过程为:先获取图像->找到纯黑色的区域->分析黑色的间隔->根据间隔计算时间. 其中根据图像获取的一行数据如右侧图,1为黑色区域,0为非黑色区域,app
根据一、0即可以计算宽度了.ide
1 package com.hennsun.decode; 2 3 import android.graphics.Bitmap; 4 import android.util.Log; 5 public class DecodeImage { 6 7 /* 8 * -16777216 表示ARGB的纯黑色 9 * */ 10 public static byte[] getLightValue(Bitmap image){ 11 int wight = image.getWidth(); 12 int hight = image.getHeight(); 13 int loc = (int)(hight*8/9.5); 14 byte[] dataA = new byte[wight]; 15 for(int i = 0;i<wight;i++){ 16 if(image.getPixel(i, loc) == -16777216) 17 dataA[i] = 1; 18 } 19 return dataA; 20 } 21 22 23 /** 24 * 获得间隔宽度 25 * @param light 26 * @return 27 */ 28 public static int decodeGap(byte[] light){ 29 int start = 0,end1 =0,end2 = light.length ; 30 for(int i = 0;i<light.length-1;i++){ 31 if(light[i+1]<light[i]){ 32 start = i+1; 33 Log.d("Plug", "start is " + Integer.toString(start)); 34 break; 35 } 36 } 37 for(int i = start;i<light.length-1;i++){ 38 if(light[i+1]>light[i]){ 39 end1 = i; 40 Log.d("Plug", "end1 is " + Integer.toString(end1)); 41 break; 42 } 43 } 44 for(int i = end1+1 ;i<light.length-1;i++){ 45 if(light[i+1]<light[i]){ 46 end2 = i; 47 Log.d("Plug", "end2 is " + Integer.toString(end2)); 48 break; 49 } 50 } 51 if(start == end2+1) 52 return 0; 53 else 54 return (end1+end2)/2 - start; 55 } 56 57 /** 58 * 得到点击的时间 59 * @param image 游戏的界面 60 * @param index 为 像素值/ms 61 * @return 62 */ 63 public static float getTime(Bitmap image,float index){ 64 float time = 0; 65 int gap = 0; 66 byte[] gray = getLightValue(image); 67 gap = decodeGap(gray); //return pixe counts. 68 time = gap/index; //这里采用可调整系数。 69 Log.d("Plug","the width of the gap is "+Float.toString((float) (5.35*gap/720))+"cm"); 70 return time; 71 72 } 73 74 }
关于屏幕的截图,我可使用adb方式,脚本以下。固然方式比较的多,我选择了相对比较简单的。wordpress
:abc adb shell screencap -p /sdcard/Demo/screen.bmp ping 127.0.0.1 -n 10>null goto abc
或下面这种方式均可以实现截屏,我已经验证彻底没有问题,可是对就处理流程就有点不一样了.学习
1 package com.hennsun.runtime; 2 3 import java.io.BufferedOutputStream; 4 import java.io.PrintStream; 5 6 import android.util.Log; 7 8 9 public class CaptureScreen { 10 /** 11 * http://my.oschina.net/u/2241960/blog/330485 12 * @param path 图片保存路径 13 */ 14 public static void screenshot(String path){ 15 Process process = null; 16 Log.d("Plug","start to capture screen"); 17 try{ 18 process = Runtime.getRuntime().exec("su"); 19 PrintStream outputStream = null; 20 try { 21 outputStream = new PrintStream(new BufferedOutputStream(process.getOutputStream(), 8192)); 22 outputStream.println("screencap -p " + path); 23 outputStream.flush(); 24 }catch(Exception e){ 25 e.printStackTrace(); 26 } finally { 27 if (outputStream != null) { 28 outputStream.close(); 29 } 30 } 31 process.waitFor(); 32 }catch(Exception e){ 33 e.printStackTrace(); 34 }finally { 35 if(process != null){ 36 process.destroy(); 37 } 38 } 39 } 40 }
模拟Touch,我是从下面的参考的部分获取的代码,根据时间间隔即可以操做Touch事件了,不过须要软件Root权限,代码以下:idea
1 /** 2 * simulate Click 3 * @param time 4 */ 5 private void simulateClick(float time){ 6 try{ 7 Process process = Runtime.getRuntime().exec("su"); 8 DataOutputStream os = new DataOutputStream(process.getOutputStream()); 9 //String cmd = "/system/bin/input tap 100 200\n"; 10 //time 为 ms 11 String timeS = String.valueOf((int)time); 12 Log.d("Plug", "the necessary time is "+timeS); 13 String cmd = "/system/bin/input swipe 100 200 100 200 "+timeS+"\n"; 14 os.writeBytes(cmd); 15 os.writeBytes("exit\n"); 16 os.flush(); 17 os.close(); 18 process.waitFor(); 19 }catch(Exception e){ 20 21 } 22 }
以上代码仅作学习交流使用,本文原创,且勿转载!!
视频展现:
Youtube展现连接 https://www.youtube.com/watch?v=sF0PuKGJFUI&feature=youtu.be
这是国外另一个团队作了,应该是印度人,他作的比较麻烦.
https://www.youtube.com/watch?v=dJW59UliLhc
须要源码的能够访问个人 我的主页 http://www.shareideas.net/
参考:
http://w3facility.org/question/how-to-simulate-touch-from-background-service-with-sendevent-or-other-way/
http://stackoverflow.com/questions/11142843/how-can-i-use-adb-to-send-a-longpress-key-event
https://grymoire.wordpress.com/2014/09/17/remote-input-shell-scripts-for-your-android-device/