論文寫完,感受頭腦很久沒被靈感刺激了,前些天室友介紹了個小遊戲,我忽然來了靈感能夠寫的簡單的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/