Android跨程序模擬用戶操作方法(史上最全)

對于安卓系統(tǒng)來說逞泄,模擬用戶操作是一件很危險的事情,因此到目前我所使用過的系統(tǒng)(Android 7以下)均沒有開放模擬觸控權(quán)限。本文總結(jié)了目前已知可行的跨進(jìn)程觸控操作方法舵盈,基本都需要Root權(quán)限或系統(tǒng)簽名毡咏。

一驮宴、Instrumentation框架

| 項目 | 描述 |
| -------|: ------:|
| 權(quán)限要求 | 同進(jìn)程下無要求 |
| 權(quán)限要求 | 跨進(jìn)程下需要系統(tǒng)簽名 |
| 可用操作 | 點(diǎn)擊、滑動呕缭、拖拽堵泽、多點(diǎn)觸控修己、按鍵操作 |
| 上手難度 | 簡單 |

Instrumentation框架主要是用來控制和測試應(yīng)用程序的,一般用在寫單元測試的時候迎罗,可模擬用戶所有操作睬愤。

代碼如下:

Instrumentation inst = new Instrumentation();
inst.sendPointerSync(event);//發(fā)送鼠標(biāo)操作
inst.sendKeyDownUpSync(keyCode);//發(fā)送按鍵操作```

例子:模擬鼠標(biāo)滑動

//模擬按下
MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, positionX, positionY, 0);
//模擬移動
MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, positionX, positionY, 0);
//模擬抬起
MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, positionX, positionY, 0);

>    常見觸摸操作
>    public static final int ACTION_DOWN  = 0;    單點(diǎn)觸摸動作
>    public static final int ACTION_UP                     = 1;    單點(diǎn)觸摸離開動作
>    public static final int ACTION_MOVE               = 2;觸摸點(diǎn)移動動作
>    public static final int ACTION_CANCEL           = 3;觸摸動作取消
>    public static final int ACTION_OUTSIDE          = 4;觸摸動作超出邊界
>    public static final int ACTION_POINTER_DOWN     = 5;多點(diǎn)觸摸動作
>    public static final int ACTION_POINTER_UP       = 6;多點(diǎn)離開動作

PS:在同進(jìn)程下,可以使用 *view.onTouchEvent(motionEvent);* 來對控件輸入模擬操作

###系統(tǒng)權(quán)限獲取方法
在AndroidManifest.xml文件中增加系統(tǒng)權(quán)限 android:sharedUserId="android.uid.system"纹安,并對生成的apk包尤辱,進(jìn)行系統(tǒng)簽名

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/6338331-fbc3100a6193c30f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

系統(tǒng)簽名有兩種方法
####方法一:使用簽名文件簽名方法
Android的簽名文件存放于系統(tǒng)源碼的 build/target/product/security/目錄下
    ![](http://upload-images.jianshu.io/upload_images/6338331-378f87f773ef75ab?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)    該目錄下有 media.pk8、media.x509.pem厢岂、platform.pk8光督、platform.x509.pem、shared.pk8塔粒、shared.x509.pem结借、testkey.pk8、testkey.x509.pem等簽名文件窗怒,不同的簽名文件映跟,對應(yīng)不同的權(quán)限。Android默認(rèn)的簽名文件為testkey.pk8扬虚、testkey.x509.pem努隙。
將對應(yīng)權(quán)限的簽名文件platform.pk8、platform.x509.pem辜昵, 簽名工具 signapk.jar荸镊, 以及需要簽名的apk(假設(shè) old.apk) 放到同一目錄下,打開linux終端(windows cmd也可以)堪置,進(jìn)入該目錄躬存,進(jìn)行重新簽名:
    java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk
得到的new.apk就是帶系統(tǒng)簽名的安裝包了。

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/6338331-81ea153d2266673b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

####方法二:在系統(tǒng)源碼環(huán)境下用make來編譯(需Linux環(huán)境)
** 1.修改Android.mk文件**
 Android.mk文件時在Linux下用交叉編譯連編譯的時候才用到的舀锨,eclipse中不會自動生成岭洲。我們在Android.mk文件中添加LOCAL_CERTIFICATE := platform這一行。例如:
>LOCAL_PATH:= $(call my-dir)  
include $(CLEAR_VARS)  
LOCAL_SRC_FILES := $(call all-java-files-under, src)  
LOCAL_PACKAGE_NAME := Settings  
LOCAL_CERTIFICATE := platform  
LOCAL_PROGUARD_FLAG_FILES := proguard.flags  

 ** 2.把項目放到源碼下坎匿,用mm命令編譯**


***
#二盾剩、ADB命令 input
| 項目 | 描述 |
| -------|: ------:|
| 權(quán)限要求 | 需要Root權(quán)限|
| 可用操作 | 點(diǎn)擊、直線滑動替蔬、拖拽告私、按鍵操作、英文輸入 |
| 上手難度 | 簡單 |
*用adb的input命令來模擬簡單的輸入承桥,用法比較受限*

>usage: input ...
input text //輸入文字(中文不支持)
input keyevent //keyevent按鍵
input [touchscreen|touchpad|touchnavigation] tap <x> <y>//點(diǎn)擊屏幕
input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> //屏幕滑動 
input rotationevent 0 1->90 2->180 3->270> //順時針旋轉(zhuǎn)


代碼如下:

//su命令函數(shù)
public class UtilShell{
private static DataOutputStream os = null;
public static final boolean exe(String cmd){
try {
if (os == null) {
Process process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
}
os.writeBytes(cmd + "\n");
os.flush();
return true;
}catch (IOException ex) {
Log.w("ROOT", "Can't get root access", ex);
} catch (SecurityException ex) {
Log.w("ROOT", "Can't get root access", ex);
} catch (Exception ex) {
Log.w("ROOT", "Error executing internal operation", ex);
}
return false;
}
}

//模擬點(diǎn)擊坐標(biāo)(222,333)代碼
UtilShell.exe("input touchscreen tap "+222+" "+333);

>附按鍵表
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

***
#三驻粟、Shell命令 sendevent
| 項目 | 描述 |
| -------|: ------:|
| 權(quán)限要求 | 需要Root權(quán)限|
| 可用操作 | 點(diǎn)擊、滑動凶异、拖拽 |
| 上手難度 | 較難 |

*getevent&sendevent 是Android系統(tǒng)下的一個工具蜀撑,可以模擬多種按鍵和觸屏操作挤巡,產(chǎn)生的是raw event,raw event經(jīng)過event hub處理產(chǎn)生最終的gesture事件屯掖,sendevent用于發(fā)送input事件玄柏,源碼位于Android SDK的system/core/toolbox下(sendevent.c getevent.c)。*

###用法
####1. 使用所有g(shù)etevent命令贴铜,輸出所有event設(shè)備的基本信息
**注意:這里的數(shù)字都是16進(jìn)制粪摘。**
>Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]  
    -t: show time stamps  
    -n: don't print newlines  
    -s: print switch states for given bits  
    -S: print all switch states  
    -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)  
    -d: show HID descriptor, if available  
    -p: show possible events (errs, dev, name, pos. events)  
    -i: show all device info and possible events  
    -l: label event types and names in plain text  //將type、code绍坝、value以對應(yīng)的常量名稱顯示
    -q: quiet (clear verbosity mask)  
    -c: print given number of events then exit   //輸出x條信息后退出
    -r: print rate events are received  

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/6338331-9735a4341d0cb192.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


####2. 使用sendevent命令模擬操作
**注意:這里的數(shù)字都是10進(jìn)制徘意。**
>命令用法 sendevent [device] [type] [code] [value]
*具體定義可從kernel/include/linux/input.h中獲得
提供個鏈接 http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/input.h*

>情況1:在某坐標(biāo)點(diǎn)上點(diǎn)擊一次(x坐標(biāo)為40,y坐標(biāo)為210)
adb shell sendevent /dev/input/event0 3 0 40    //鼠標(biāo)移到x坐標(biāo)40
adb shell sendevent /dev/input/event0 3 1 210  //鼠標(biāo)移到y(tǒng)坐標(biāo)210
adb shell sendevent /dev/input/event0 1 330 1 //鼠標(biāo)按下
adb shell sendevent /dev/input/event0 0 0 0 //同步(不可缺少)
adb shell sendevent /dev/input/event0 1 330 0 //鼠標(biāo)抬起
adb shell sendevent /dev/input/event0 0 0 0 //同步(不可缺少)

>情況2:模擬滑動軌跡(開始于[100,200]轩褐,止于[108,300])
adb shell sendevent /dev/input/event0 3 0 100 //鼠標(biāo)移到x坐標(biāo)100
adb shell sendevent /dev/input/event0 3 1 200 //鼠標(biāo)移到y(tǒng)坐標(biāo)200
   
adb shell sendevent /dev/input/event0 1 330 1 //鼠標(biāo)按下
adb shell sendevent /dev/input/event0 0 0 0    //同步
   
adb shell sendevent /dev/input/event0 3 0 101 //鼠標(biāo)移到x坐標(biāo)101
adb shell sendevent /dev/input/event0 0 0 0    //同步
……………………     //需一點(diǎn)一點(diǎn)移動椎咧,這里省略
adb shell sendevent /dev/input/event0 3 0 108 //鼠標(biāo)移到x坐標(biāo)108
adb shell sendevent /dev/input/event0 0 0 0   //同步
   
adb shell sendevent /dev/input/event0 1 330 0 //鼠標(biāo)抬起
adb shell sendevent /dev/input/event0 0 0 0   //同步

代碼如下:

//模擬操作與input命令相似
UtilShell.exe("sendevent /dev/input/event0 0 0 0");

*此方法基本能滿足模擬操作的所有要求,據(jù)說有一款叫aPaint的軟件對此方法開發(fā)有極大幫助*
***
#四把介、新增虛擬USB鼠標(biāo)設(shè)備
| 項目 | 描述 |
| -------|: ------:|
| 權(quán)限要求 | 需要修改系統(tǒng)文件|
| 可用操作 | 所有鼠標(biāo)操作 |
| 上手難度 | 極難 |
暫無思路勤讽,僅供參考!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拗踢,一起剝皮案震驚了整個濱河市脚牍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巢墅,老刑警劉巖诸狭,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異君纫,居然都是意外死亡驯遇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門蓄髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叉庐,“玉大人,你說我怎么就攤上這事会喝《傅” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵好乐,是天一觀的道長。 經(jīng)常有香客問我瓦宜,道長蔚万,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任临庇,我火速辦了婚禮反璃,結(jié)果婚禮上昵慌,老公的妹妹穿的比我還像新娘。我一直安慰自己淮蜈,他們只是感情好斋攀,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梧田,像睡著了一般淳蔼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裁眯,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天鹉梨,我揣著相機(jī)與錄音,去河邊找鬼穿稳。 笑死存皂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逢艘。 我是一名探鬼主播旦袋,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼它改!你這毒婦竟也來了疤孕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤搔课,失蹤者是張志新(化名)和其女友劉穎胰柑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爬泥,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柬讨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了袍啡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踩官。...
    茶點(diǎn)故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖境输,靈堂內(nèi)的尸體忽然破棺而出蔗牡,到底是詐尸還是另有隱情,我是刑警寧澤嗅剖,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布辩越,位于F島的核電站,受9級特大地震影響信粮,放射性物質(zhì)發(fā)生泄漏黔攒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望督惰。 院中可真熱鬧不傅,春花似錦、人聲如沸赏胚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觉阅。三九已至崖疤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間留拾,已是汗流浹背戳晌。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痴柔,地道東北人沦偎。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像咳蔚,于是被迫代替她去往敵國和親豪嚎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容