Android模擬點選螢幕,實現按鍵精靈點選螢幕功能
我在實現安卓模擬點選螢幕固定位置時嘗試了很多方法,碰了不少壁,現在我將我實現的方法分享給大家,以及我嘗試過的方法也分享給大家,讓大家在開發的路上少走些彎路。
首先我嘗試用安卓輔助功能AccessibilityService類實現模擬螢幕點選,但是這個類只能找到頁面的控制元件,然後對控制元件進行模擬點選,不能實現對螢幕的某個位置進行點選,這個方法失敗後我就試了另一種Instrumentation方法,這種方法確實可以點選螢幕上任何位置,而且點選事件可以生效,但是退出程式就不能進行了,程式出現錯誤,提示沒有INJECT_EVENTS許可權,但是加入INJECT_EVENTS許可權後,還是出錯,查了一下資料,說可以在新增android:sharedUserId="android.uid.system"獲取系統共享簽名,但是加入後生成的APK無法安裝的手機上。
使用Instrumentation方法點選手機螢幕的任何位置
import java.io.IOException;
import android.app.Instrumentation;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
public class ThreadClass extends Thread {
private int x,y;
//400,689
@Override
public void run() {
while(true)
{
//利用ProcessBuilder執行shell命令
/*String[] order = {
"input",
"tap",
"" + x,
"" + y
};
Log.d("點選位置", x+","+y);
try {
new ProcessBuilder(order).start();
} catch (IOException e) {
e.printStackTrace();
}*/
// 可以不用在 Activity 中增加任何處理,各 Activity 都可以響應
try {
Instrumentation inst = new Instrumentation();
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),
MotionEvent.ACTION_DOWN, x, y, 0));
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),
MotionEvent.ACTION_UP, x, y, 0));
Log.d("點選位置", x+","+y);
}catch(Exception e) {
Log.e("Exception when sendPointerSync", e.toString());
}
//執行緒睡眠3s
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public ThreadClass(int x,int y){
this.x=x;
this.y=y;
}
}
其中x,y是需要點選的螢幕左邊,以左上角為原點的直角座標系統
加入INJECT_EVENTS許可權
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
新增android:sharedUserId="android.uid.system"位置如下,寫安卓的應該都可以明白
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.clickservice"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system"
>
為了解決這個錯誤,我按照網上說的方法進行,使用安卓簽名工具SignApk.jar對編譯的apk進行簽名,簽名後的APK還是無法安裝在手機上,還有一種解決這問題的方法就是使用android原始碼編譯,相信這種方法會讓大多數人無從下手,光將android原始碼編譯的環境搭配起來都不是一件容易的事,有興趣的可以嘗試一下這種方法,下面就步入我們今天要講的主題adb shell。
首先我們在windows下通過adb shell控制手機,在此之前,保證你的手機已經連線電腦,進入eclipse adt開發環境下的adb所在檔案目錄,以我的為例,路徑為..\adt-bundle-windows-x86-20130917\sdk\platform-tools,以下是我的目錄截圖,可以對著找到該目錄。
在該目錄下,按下shift鍵後點擊滑鼠右鍵,在彈出視窗中選擇“在此處開啟命令視窗(W)”,也可以直接cmd進入這目錄,在命令視窗輸入:adb shell 進入adb shell命令狀態,此後就可以用shell命令控制你的手機了。
我在此就簡單介紹一些命令,要想詳細瞭解的去下面兩篇部落格
自己動手開發精簡版按鍵精靈
Android模擬螢幕點選事件
getevent -p
檢視哪個裝置包含event 體系裡 寬(0035)和高(0036),那麼這個裝置就是我們的安卓手機,例如這裡的裝置名稱為/dev/input/event1
模擬傳送事件
getevent/sendevent是Android系統下的一個工具,可以模擬多種按鍵和觸屏操作,產生的是raw event,raw event經過event hub處理產生最終的gesture事件。getevent用於獲取當前系統input裝置的一些引數和實時事件的資料;sendevent用於傳送input事件,這倆命令的作用就是相當於解放了手,可以通過命令直接呼叫Linux底層來控制手機,工具的原始碼位於Android SDK的system/core/toolbox下(sendevent.c getevent.c)。
傳送鍵盤事件
用法說明:
adb shell input keyevent “value”
input text
input keyevent
input tap
input swipe
如上,input後可以跟很多引數, text相當於輸入內容,keyevent相當於手機物理或是螢幕按鍵,tap相當於touch事件,swipe相當於滑動~~是不是很贊?先列舉 input keyevent 幾個比較常用的code值:
input keyevent 3 // Home
input keyevent 4 // Back
input keyevent 19 //Up
input keyevent 20 //Down
input keyevent 21 //Left
input keyevent 22 //Right
input keyevent 23 //Select/Ok
input keyevent 24 //Volume+
input keyevent 25 // Volume-
input keyevent 82 // Menu 選單
附:input keyevent所對應全部key值:
KeyCode Keyevent Value
KEYCODE_MENU 1
KEYCODE_SOFT_RIGHT 2
KEYCODE_HOME 3
KEYCODE_BACK 4
KEYCODE_CALL 5
KEYCODE_ENDCALL 6
KEYCODE_0 7
KEYCODE_1 8
KEYCODE_2 9
KEYCODE_3 10
KEYCODE_4 11
KEYCODE_5 12
KEYCODE_6 13
KEYCODE_7 14
KEYCODE_8 15
KEYCODE_9 16
KEYCODE_STAR 17
KEYCODE_POUND 18
KEYCODE_DPAD_UP 19
KEYCODE_DPAD_DOWN 20
KEYCODE_DPAD_LEFT 21
KEYCODE_DPAD_RIGHT 22
KEYCODE_DPAD_CENTER 23
KEYCODE_VOLUME_UP 24
KEYCODE_VOLUME_DOWN 25
KEYCODE_POWER 26
KEYCODE_CAMERA 27
KEYCODE_CLEAR 28
KEYCODE_A 29
KEYCODE_B 30
KEYCODE_C 31
KEYCODE_D 32
KEYCODE_E 33
KEYCODE_F 34
KEYCODE_G 35
KEYCODE_H 36
KEYCODE_I 37
KEYCODE_J 38
KEYCODE_K 39
KEYCODE_L 40
KEYCODE_M 41
KEYCODE_N 42
KEYCODE_O 43
KEYCODE_P 44
KEYCODE_Q 45
KEYCODE_R 46
KEYCODE_S 47
KEYCODE_T 48
KEYCODE_U 49
KEYCODE_V 50
KEYCODE_W 51
KEYCODE_X 52
KEYCODE_Y 53
KEYCODE_Z 54
KEYCODE_COMMA 55
KEYCODE_PERIOD 56
KEYCODE_ALT_LEFT 57
KEYCODE_ALT_RIGHT 58
KEYCODE_SHIFT_LEFT 59
KEYCODE_SHIFT_RIGHT 60
KEYCODE_TAB 61
KEYCODE_SPACE 62
KEYCODE_SYM 63
KEYCODE_EXPLORER 64
KEYCODE_ENVELOPE 65
KEYCODE_ENTER 66
KEYCODE_DEL 67
KEYCODE_GRAVE 68
KEYCODE_MINUS 69
KEYCODE_EQUALS 70
KEYCODE_LEFT_BRACKET 71
KEYCODE_RIGHT_BRACKET 72
KEYCODE_BACKSLASH 73
KEYCODE_SEMICOLON 74
KEYCODE_APOSTROPHE 75
KEYCODE_SLASH 76
KEYCODE_AT 77
KEYCODE_NUM 78
KEYCODE_HEADSETHOOK 79
KEYCODE_FOCUS 80
KEYCODE_PLUS 81
KEYCODE_MENU 82
KEYCODE_NOTIFICATION 83
KEYCODE_SEARCH 84
TAG_LAST_KEYCODE 85
通過以上的介紹你應該對adb shell命令有所瞭解了吧,但是如何用程式碼來實現呢,以下就是程式碼執行shell命令
/**
* 執行shell命令
*
* @param cmd
*/
private void execShellCmd(String cmd) {
try {
// 申請獲取root許可權,這一步很重要,不然會沒有作用
Process process = Runtime.getRuntime().exec("su");
// 獲取輸出流
OutputStream outputStream = process.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(
outputStream);
dataOutputStream.writeBytes(cmd);
dataOutputStream.flush();
dataOutputStream.close();
outputStream.close();
} catch (Throwable t) {
t.printStackTrace();
}
}
在想要執行的地方呼叫上面函式:
execShellCmd("getevent -p");
execShellCmd("sendevent /dev/input/event1 1 158 1");
execShellCmd("sendevent /dev/input/event1 1 158 0");
execShellCmd("input keyevent 3");//home
execShellCmd("input text 'helloworld!' ");
execShellCmd("input tap 168 252");
execShellCmd("input swipe 100 250 200 280");
注意使用sendevent執行事件時,可以看到sendevent需要4個引數即:device,type,code,value。這些值可以由input子系統定義,也可以從getevent裡面獲取。type其實就是和getevent中的支援事件型別所對應的, value=1是按下,value=0是彈起,也就是說只有當兩個命令同時執行時命令才會生效,也就是下面兩句要先後一併執行
execShellCmd("sendevent /dev/input/event1 1 158 1");
execShellCmd("sendevent /dev/input/event1 1 158 0");
如果要退出程式後,繼續執行模擬點選螢幕,只要寫一個後臺執行的Service掛在後臺執行即可,到此模擬點選手機螢幕的功能就實現了
本文章對應程式,實現按鍵精靈模擬點選原始碼:http://download.csdn.net/download/yuanhengzhw/10254876
---------------------
作者:浪遏飛舟之心亙
來源:CSDN
原文:https://blog.csdn.net/yuanhengzhw/article/details/70435626
版權宣告:本文為博主原創文章,轉載請附上博文連結!