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

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: 继续在网上搜索安卓按键模拟(其实那时都不知道用什么关键字好了,能想到的关键字都用遍了,但是搜索出来的结果,都是之前提到的那几个依赖源码环境和系统权限的方案)。发现有很多介绍ADB调试,向手机发送按键事件的文章。
继续在网上搜索安卓按键模拟(其实那时都不知道用什么关键字好了,能想到的关键字都用遍了,但是搜索出来的结果,都是之前提到的那几个依赖源码环境和系统权限的方案)。发现有很多介绍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 + "\n");
	}
}

 

 
写这篇文章的主要目的,并不是要强调这件事的难度,也不只是为了提出问题的解决方案(那样就没必要写前面那么多过程了)。而是想把我解决问题的过程完整的写出来,对我而言算是一个记录,对读者而言,没准能从中找到一些东西。
 
解决这个问题之后,后来意外的发现,这个问题其实有人已经解决了,并且发了博客。不幸的是,那篇博客被大量使用前两种思路的博客掩埋了,当时我怎么也没找到。这篇博客地址在此:
 
 
顺便说明一点,这篇博客中作者提到的缺点:反应速度较慢。前面提到我也越到了同样的问题,也已经给出了解决方案。
 
本文由 jzj1993原创,转载请注明来源: http://www.hainter.com/android-key-simulation
(标注了原文链接的文章除外)
 
android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
 
Android中使用隐藏API(大量图解)  
 

通过Runtime实现,代码如下:

[html]  view plain copy
 
  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 plain copy
 
  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;   
相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
4月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
87 2
基于Android P,自定义Android开机动画的方法
|
4月前
|
Android开发
基于android-11.0.0_r39,系统应用的手动签名方法和过程
本文介绍了基于Android 11.0.0_r39版本进行系统应用手动签名的方法和解决签名过程中遇到的错误,包括处理`no conscrypt_openjdk_jni-linux-x86_64`和`RegisterNatives failed`的问题。
206 2
|
2月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
74 15
Android 系统缓存扫描与清理方法分析
|
4月前
|
存储 安全 Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
【8月更文挑战第13天】随着Android系统的更新,权限管理变得至关重要。尤其从Android 6.0起,引入了动态权限请求,增强了用户隐私保护并要求开发者实现更精细的权限控制。本文采用问答形式,深入探讨动态权限请求机制与最佳实践,并提供示例代码。首先解释了动态权限的概念及其重要性;接着详述实现步骤:定义、检查、请求权限及处理结果;最后总结了六大最佳实践,包括适时请求、解释原因、提供替代方案、妥善处理拒绝情况、适应权限变更及兼容旧版系统,帮助开发者打造安全易用的应用。
81 0
|
3月前
|
ARouter 测试技术 API
Android经典面试题之组件化原理、优缺点、实现方法?
本文介绍了组件化在Android开发中的应用,详细阐述了其原理、优缺点及实现方式,包括模块化、接口编程、依赖注入、路由机制等内容,并提供了具体代码示例。
50 2
|
3月前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
75 2
|
4月前
|
Android开发
Android在rootdir根目录创建自定义目录和挂载点的方法
本文介绍了在Android高通平台的根目录下创建自定义目录和挂载点的方法,通过修改Android.mk文件并使用`LOCAL_POST_INSTALL_CMD`变量在编译过程中添加目录,最终在ramdisk.img的系统根路径下成功创建了`/factory/bin`目录。
233 1
|
4月前
|
开发工具 uml git
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
本文分享了下载AOSP源码的方法,包括如何使用repo工具和处理常见的repo sync错误,以及配置Python环境以确保顺利同步特定版本的AOSP代码。
559 0
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
|
4月前
|
Android开发 开发者 Kotlin
Android 多进程情况下判断应用是否处于前台或者后台
本文介绍在多进程环境下判断Android应用前后台状态的方法。通过`ActivityManager`和服务信息`RunningAppProcessInfo`可有效检测应用状态,优化资源使用。提供Kotlin代码示例,帮助开发者轻松集成。
298 8
|
4月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。