Android 系统下模拟触点击的功能与权限

最近在研究手机与车载设备之间互联的功能,有一些问题不是很清楚,特别 Android 的功能。所以分别在 WinCE 和 Android 的论坛发了一个帖子,希望可以得到大牛的指点。帖子链接如下:

WinCE:  WinCE 设备如何通过 USB 与 Android 手机互联?

Android: Android 应用如何模拟触屏点击动作?

得到了大家的积极回复,很多问题有了一定的答案。虽然到目前为止,还没有彻底的将技术问题搞通,但也差不了多少了!

通过 Instrumentation 来模拟屏幕点击,在本应用的界面,不用增加如下的处理也可以正常响应。但本应用后台运行后,想控制其它的应用或系统应用时,出现权限不允许的错误。

在一台已经 ROOT 的设备上,且在 manifest 中增加了:

<uses-permission android:name="android.permission.INJECT_EVENTS" />  

调用如下函数,让应用获取 ROOT 的权限后,本应用后台运行后模拟屏幕点击仍然出错。

 1 public static boolean runRootCommand(String command) {  
 2     Process process = null;  
 3     DataOutputStream os = null;  
 4     try {  
 5         process = Runtime.getRuntime().exec("su");  
 6         os = new DataOutputStream(process.getOutputStream());  
 7         os.writeBytes(command + "
");  
 8         os.writeBytes("exit
");  
 9         os.flush();  
10         process.waitFor();  
11     } catch (Exception e) {  
12         Log.d(TAG,  "the device is not rooted,  error message: " + e.getMessage());  
13         return false;  
14     } finally {  
15         try {  
16             if (os != null) {  
17             os.close();  
18         }  
19         if(process != null) {  
20             process.destroy();  
21         }  
22         } catch (Exception e) {  
23             e.printStackTrace();  
24         }  
25     }  
26     return true;  
27 }  
1 09-29 09:36:18.424: E/AndroidRuntime(1872): FATAL EXCEPTION: Thread-12  
2 09-29 09:36:18.424: E/AndroidRuntime(1872): java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission  
3 09-29 09:36:18.424: E/AndroidRuntime(1872):     at android.os.Parcel.readException(Parcel.java:1353)  
4 09-29 09:36:18.424: E/AndroidRuntime(1872):     at android.os.Parcel.readException(Parcel.java:1307)  
5 09-29 09:36:18.424: E/AndroidRuntime(1872):     at android.view.IWindowManager$Stub$Proxy.injectPointerEvent(IWindowManager.java:949)  
6 09-29 09:36:18.424: E/AndroidRuntime(1872):     at android.app.Instrumentation.sendPointerSync(Instrumentation.java:937)  
7 09-29 09:36:18.424: E/AndroidRuntime(1872):     at com.jia.leozhengfirstapp.SocketClient$SocketReceiveThread.run(SocketClient.java:439)  

1) 模拟屏幕点击实现的方法一

 1 // 模拟屏幕点击事件 - 只在 Activity 中有用  
 2 public void setMouseClick(){  
 3     MotionEvent evenDownt = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis() + 100,  
 4     MotionEvent.ACTION_DOWN, 100, 400, 0);  
 5   dispatchTouchEvent(evenDownt);  
 6   MotionEvent eventUp = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis() + 100,  
 7         MotionEvent.ACTION_UP, 100, 400, 0);  
 8   dispatchTouchEvent(eventUp);  
 9   evenDownt.recycle();  
10   eventUp.recycle();  
11 }  

2) 模拟屏幕点击实现的方法二

1 // 可以不用在 Activity 中增加任何处理,各 Activity 都可以响应  
2 Instrumentation inst = new Instrumentation();  
3 inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),   
4     MotionEvent.ACTION_DOWN, 200, 500, 0));  
5 inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),   
6     MotionEvent.ACTION_UP, 200, 500, 0));  

解决此问题,看来只有一种途径了: 获取系统权限。按网上的描述,有以下两种方法: 
(1) 在源码中编译(需要在 Linux 环境下执行)
(2) 手动添加系统签名(较为麻烦,但不必进入 Linux 环境,在 Windows 环境下就能操作)
以上方法也是有缺陷的: 这样生成的程序只有在原始的 Android 系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。
要是别家公司做的 Android 上连安装都安装不了。
试试原始的 Android 中的 key 来签名,程序在模拟器上运行 OK,不过放到 G3 上安装直接提示:
"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。

以前回复的内容:

(1)有人在回复中提到自动化测试工具,所以偶也了解了一下,在 WinCE 下可能无法实现,因为需要 ADB【可以移植折】。自动化测试可以使用 monkey 工具,monkey 工具运行时直接通过 ADB Shell 连接到设备或模拟器,并且产生一个用户和系统事件的伪随机流。相比较 monkeyrunner 工具是通过工作站通过 API 发送特定的命令和事件来控制设备或模拟器。 The monkey tool runs in an adb shell directly on the device or emulator and generates pseudo-random streams of user and system events. In comparison, the monkeyrunner tool controls devices and emulators from a workstation by sending specific commands and events from an API. 总的来说,monkey 主要应用在压力和可靠性测试上,运行该命令可以随机地向目标程序发送各种模拟键盘事件流,并且可以自己定义发送的次数,以此观察被测应用程序的稳定性和可靠性,应用起来也比较简单,记住那几个命令就行了。而 monkeyrunner 呢,相比之下会强大一些,它主要可应用于功能测试,回归测试,并且可以自定义测试扩展,灵活性较强,并且测试人员可以完全控制。

(2)镜像技术相关的技术主要有:
苹果(Apple)的AirPlay Mirroring
英特尔(Intel)的WiDi
AMD 的AWD 3.0
WiGig联盟的WiGig
晶像(Silicon Image)的Ultra Gig(Wireless HD)
WHDI联盟的无线数字家庭接口(WHDI)
汽车联机联盟(Car Connectivity Consortium)的MirrorLink
以及Miracast
除WiGig及UltraGig使用的是60GHz的频段,其他的技术都是使用2.4GHz或5GHz的频段,不同的技术也有不同的传输速率及影音格式的规范。
AirPlay Mirroring凭借着其iOS及Mac装置的热卖,在此技术领域占有一定的比例;
WiDi以内建于英特尔笔记本电脑平台上的优势打入市场;WiGig技术的传输率可到达7Gbit/s,2013年初又与Wi-Fi联盟合并,因此未来的发展值得关注。
WHDI 也由于其独占性,须看制造商是否支持;Gig的传输率可到达28Gbit/s,不过该技术目前由晶像独占,得看设备制造商是否愿意采用;

MirrorLink主要的应用目标是在车载系统,并同时定义有线及无线的应用,由于是汽车联机联盟主推,因此比较有机会被车商所采用;
而Miracast由Wi-Fi联盟提出,并基于既有的Wi-Fi技术,容易与现有的无线产品结合,因此开发厂商较多,特别是英特尔宣布WiDi3.5版将与Mircast兼容

原文地址:https://www.cnblogs.com/91program/p/5192375.html