• 安卓使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)


    继续在网上搜索安卓按键模拟(其实那时都不知道用什么关键字好了,能想到的关键字都用遍了,但是搜索出来的结果,都是之前提到的那几个依赖源码环境和系统权限的方案)。发现有很多介绍ADB调试,向手机发送按键事件的文章。刚好之前做过在Root权限下,用Java调用安卓底层的Linux Shell,然后执行pm指令进行APK的安装卸载。这时我突发奇想,能否用Shell调用ADB指令呢?
     
    于是就进行了尝试,使用Java执行Runtime.getRuntime().exec(“su”).getOutputStream(),获取了一个具有Root权限的Process的输出流对象,向其中写入字符串即可以Root权限被Shell执行,ADB模拟按键的指令为 “input keyevent keyCode”,keyCode为按键的键值,例如KeyEvent.KEYCODE_VOLUME_UP表示音量加。
     
    编译完程序安装执行,终于实现了预期的效果,当时非常高兴。至于触屏或鼠标事件,只要调用相应的ADB指令即可。但是有一点问题,就是反应速度非常慢,尤其是连续模拟多个按键的时候,甚至会死机。而按键精灵运行的就相当流畅,我又开始好奇按键精灵是怎么实现的。
     
    后来终于还是找到了原因,模拟按键时,不应每次都调用Runtime.getRuntime().exec(“su”),因为每次调用这个代码的时候,都会获取Runtime实例,并且执行”su”请求Root权限,反应就会很慢(我的理解是相当于每次都新开一个命令行窗口);而应该只是在一开始执行一次,并获取一个OutputStream实例,后来每次执行一条Shell指令,只需向其中写入相应字符串,这样就快了很多。
     
    下面贴出可用的代码。要求设备已经Root,不需要其他任何特殊权限或签名。由于用的是ADB指令,兼容性也不会有太大问题。首次运行程序时(其实也就是执行Runtime.exec(“su”)的时候),会请求Root权限。
     
    /**
     * 用root权限执行Linux下的Shell指令
     * 
     * @author jzj
     * @since 2014-09-09
     */
    public class RootShellCmd {
    
    	private OutputStream os;
    
    	/**
    	 * 执行shell指令
    	 * 
    	 * @param cmd
    	 *            指令
    	 */
    	public final void exec(String cmd) {
    		try {
    			if (os == null) {
    				os = Runtime.getRuntime().exec("su").getOutputStream();
    			}
    			os.write(cmd.getBytes());
    			os.flush();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	/**
    	 * 后台模拟全局按键
    	 * 
    	 * @param keyCode
    	 *            键值
    	 */
    	public final void simulateKey(int keyCode) {
    		exec("input keyevent " + keyCode + "
    ");
    	}
    }
     
    写这篇文章的主要目的,并不是要强调这件事的难度,也不只是为了提出问题的解决方案(那样就没必要写前面那么多过程了)。而是想把我解决问题的过程完整的写出来,对我而言算是一个记录,对读者而言,没准能从中找到一些东西。
     
    解决这个问题之后,后来意外的发现,这个问题其实有人已经解决了,并且发了博客。不幸的是,那篇博客被大量使用前两种思路的博客掩埋了,当时我怎么也没找到。这篇博客地址在此:
     
     
    顺便说明一点,这篇博客中作者提到的缺点:反应速度较慢。前面提到我也越到了同样的问题,也已经给出了解决方案。
     
     
    android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
     
    Android中使用隐藏API(大量图解)  
     

    通过Runtime实现,代码如下:

    [html] view plaincopy
     
    1. try  
    2. {  
    3.     String keyCommand = "input keyevent " + KeyEvent.KEYCODE_MENU;  
    4.     Runtime runtime = Runtime.getRuntime();  
    5.     Process proc = runtime.exec(keyCommand);  
    6. }  
    7. catch (IOException e)  
    8. {  
    9.     // TODO Auto-generated catch block  
    10.     e.printStackTrace();  
    11. }  

    这个代码是模拟菜单键,模拟其它按键只需将KeyEvent.KEYCODE_MENU替换成其它键值。

    缺点:反应速度较慢

    以下附带各KeyCode值:

    [html] view plaincopy
     
    1. KEYCODE_UNKNOWN=0;   
    2.   
    3. KEYCODE_SOFT_LEFT=1;   
    4.   
    5. KEYCODE_SOFT_RIGHT=2;   
    6.   
    7. KEYCODE_HOME=3;   
    8.   
    9. KEYCODE_BACK=4;   
    10.   
    11. KEYCODE_CALL=5;   
    12.   
    13. KEYCODE_ENDCALL=6;   
    14.   
    15. KEYCODE_0=7;   
    16.   
    17. KEYCODE_1=8;   
    18.   
    19. KEYCODE_2=9;   
    20.   
    21. KEYCODE_3=10;   
    22.   
    23. KEYCODE_4=11;   
    24.   
    25. KEYCODE_5=12;   
    26.   
    27. KEYCODE_6=13;   
    28.   
    29. KEYCODE_7=14;   
    30.   
    31. KEYCODE_8=15;   
    32.   
    33. KEYCODE_9=16;   
    34.   
    35. KEYCODE_STAR=17;   
    36.   
    37. KEYCODE_POUND=18;   
    38.   
    39. KEYCODE_DPAD_UP=19;   
    40.   
    41. KEYCODE_DPAD_DOWN=20;   
    42.   
    43. KEYCODE_DPAD_LEFT=21;   
    44.   
    45. KEYCODE_DPAD_RIGHT=22;   
    46.   
    47. KEYCODE_DPAD_CENTER=23;   
    48.   
    49. KEYCODE_VOLUME_UP=24;   
    50.   
    51. KEYCODE_VOLUME_DOWN=25;   
    52.   
    53. KEYCODE_POWER=26;   
    54.   
    55. KEYCODE_CAMERA=27;   
    56.   
    57. KEYCODE_CLEAR=28;   
    58.   
    59. KEYCODE_A=29;   
    60.   
    61. KEYCODE_B=30;   
    62.   
    63. KEYCODE_C=31;   
    64.   
    65. KEYCODE_D=32;   
    66.   
    67. KEYCODE_E=33;   
    68.   
    69. KEYCODE_F=34;   
    70.   
    71. KEYCODE_G=35;   
    72.   
    73. KEYCODE_H=36;   
    74.   
    75. KEYCODE_I=37;   
    76.   
    77. KEYCODE_J=38;   
    78.   
    79. KEYCODE_K=39;   
    80.   
    81. KEYCODE_L=40;   
    82.   
    83. KEYCODE_M=41;   
    84.   
    85. KEYCODE_N=42;   
    86.   
    87. KEYCODE_O=43;   
    88.   
    89. KEYCODE_P=44;   
    90.   
    91. KEYCODE_Q=45;   
    92.   
    93. KEYCODE_R=46;   
    94.   
    95. KEYCODE_S=47;   
    96.   
    97. KEYCODE_T=48;   
    98.   
    99. KEYCODE_U=49;   
    100.   
    101. KEYCODE_V=50;   
    102.   
    103. KEYCODE_W=51;   
    104.   
    105. KEYCODE_X=52;   
    106.   
    107. KEYCODE_Y=53;   
    108.   
    109. KEYCODE_Z=54;   
    110.   
    111. KEYCODE_COMMA=55;   
    112.   
    113. KEYCODE_PERIOD=56;   
    114.   
    115. KEYCODE_ALT_LEFT=57;   
    116.   
    117. KEYCODE_ALT_RIGHT=58;   
    118.   
    119. KEYCODE_SHIFT_LEFT=59;   
    120.   
    121. KEYCODE_SHIFT_RIGHT=60;   
    122.   
    123. KEYCODE_TAB=61;   
    124.   
    125. KEYCODE_SPACE=62;   
    126.   
    127. KEYCODE_SYM=63;   
    128.   
    129. KEYCODE_EXPLORER=64;   
    130.   
    131. KEYCODE_ENVELOPE=65;   
    132.   
    133. KEYCODE_ENTER=66;   
    134.   
    135. KEYCODE_DEL=67;   
    136.   
    137. KEYCODE_GRAVE=68;   
    138.   
    139. KEYCODE_MINUS=69;   
    140.   
    141. KEYCODE_EQUALS=70;   
    142.   
    143. KEYCODE_LEFT_BRACKET=71;   
    144.   
    145. KEYCODE_RIGHT_BRACKET=72;   
    146.   
    147. KEYCODE_BACKSLASH=73;   
    148.   
    149. KEYCODE_SEMICOLON=74;   
    150.   
    151. KEYCODE_APOSTROPHE=75;   
    152.   
    153. KEYCODE_SLASH=76;   
    154.   
    155. KEYCODE_AT=77;   
    156.   
    157. KEYCODE_NUM=78;   
    158.   
    159. KEYCODE_HEADSETHOOK=79;   
    160.   
    161. KEYCODE_FOCUS=80;//*Camera*focus   
    162.   
    163. KEYCODE_PLUS=81;   
    164.   
    165. KEYCODE_MENU=82;   
    166.   
    167. KEYCODE_NOTIFICATION=83;   
    168.   
    169. KEYCODE_SEARCH=84;   
    170.   
    171. KEYCODE_MEDIA_PLAY_PAUSE=85;   
    172.   
    173. KEYCODE_MEDIA_STOP=86;   
    174.   
    175. KEYCODE_MEDIA_NEXT=87;   
    176.   
    177. KEYCODE_MEDIA_PREVIOUS=88;   
    178.   
    179. KEYCODE_MEDIA_REWIND=89;   
    180.   
    181. KEYCODE_MEDIA_FAST_FORWARD=90;   
    182.   
    183. KEYCODE_MUTE=91;   
  • 相关阅读:
    POJ-2112 Optimal Milking(floyd+最大流+二分)
    网络流之最大流与最小费用流入门&&模板
    0316 校赛训练赛3 解题报告
    string的子串截取
    hash题目大汇总
    Codeforces Round #235 (Div. 2)
    poj2002 -- 点的hash
    hlgHCPC2014校赛训练赛 1 BB.序列问题
    树状数组模板,RMQ模板
    从未放弃--2014.1.21
  • 原文地址:https://www.cnblogs.com/cappuccino/p/4488503.html
Copyright © 2020-2023  润新知