Stick hero "攻略", android 代碼編寫與分析(後臺截屏, 後臺模擬點擊)

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

相關文章
相關標籤/搜索