android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
来源:互联网 发布:马士兵java源代码 编辑:程序博客网 时间:2024/05/17 23:25
目的:在非源码环境下调用隐藏api实现模拟按键的功能。
首先需要下载在android4.0源码环境下编译出来的classes.jar,或者如果你有条件那么可以直接在源码环境下编译(此方法该文不讨论)。
因为我在ubuntu下没能下载完源代码,所以直接采用classes.jar导入到eclipse的方法。
1. classes.jar可以去我的资源中下载classes.jar
2. 有了classes.jar之后,在eclipse界面,拖拉jar进项目的libs目录,使用用户库的方式添加jar
可以参考Android中使用隐藏API(大量图解)
3. 导入之后隐藏的类和方法就能使用了,但是在编译时eclipse有可能会报错:Unable to execute dex: Java heap space
解决方法是修改eclipse.ini:参考博文
4. 更改了之后又可能会遇见eclipse报错: Unable to execute dex: Cannot merge new index 67208 into a non-jumbo instruction!
解决方法:project->clean;清理一下之后重新编译就好了
5. injectKeyEvent的具体用法可以参考:博文
别忘了在项目的manifest文件中添加:sharedUserId和INJECT_EVENTS权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xxxx.packagename" android:sharedUserId="android.uid.system" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INJECT_EVENTS" />
添加之后INJECT_EVENTS会报错,此时只要在菜单栏是点project->clean就可以去掉错误然后编译
6. 编译之后直接安装会安装失败,因为没有该apk没有系统权限
解决方法是:下载Signapk工具,可以去我的资源中下载
用法是在命令行下使用命令:java -jar SignApk.jar platform.x509.pem platform.pk8 app_unsigned.apk app_signed.apk
#include <stdlib.h>#include <android/log.h>#include <fcntl.h>#include <sys/ioctl.h>#include <linux/input.h>#include <dirent.h>#include <errno.h>//#include "nativemethod.h"#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "EventEmulate", __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "EventEmulate", __VA_ARGS__)#define DEV_DIR "/dev/input"#define sizeof_bit_array(bits) ((bits + 7) / 8)#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))#define ABS_MT_POSITION_X 0x35#define ABS_MT_POSITION_Y 0x36struct EVENT_INFO{int fd_touch;int fd_key;int screen_width;int screen_height;int abs_x_min;int abs_x_max;int abs_y_min;int abs_y_max;};int scan_dir(const char *dirname);int open_dev(const char *deviceName);int write_event(int fd, int type, int code, int value);void calculateXY(float x, float y, int *abs_x, int *abs_y);int containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex);struct EVENT_INFO ei;int initEVT = 0;int EVT_open(struct NATIVE_INFO *info){struct input_absinfo absinfo;if(initEVT)return 0;if(info == NULL){LOGE("info null point.");goto fail;}if(info->FB_width == 0 || info->FB_height == 0){LOGE("error width %d and height %d.", info->FB_width, info->FB_height);goto fail;}memset(&ei, 0, sizeof(ei));ei.screen_width = info->FB_width;ei.screen_height = info->FB_height;scan_dir(DEV_DIR);if(ioctl(ei.fd_touch, EVIOCGABS(ABS_X), &absinfo)) {LOGI("Error reading absolute controller ABS_X[%d]: %s", errno, strerror(errno));return;}ei.abs_x_min = absinfo.minimum;ei.abs_x_max = absinfo.maximum;if(ioctl(ei.fd_touch, EVIOCGABS(ABS_Y), &absinfo)) {LOGI("Error reading absolute controller ABS_Y[%d]: %s", errno, strerror(errno));return;}ei.abs_y_min = absinfo.minimum;ei.abs_y_max = absinfo.maximum;initEVT = 1;return 0;fail:EVT_close();return -1;}int EVT_close(){if(ei.fd_key > 0)close(ei.fd_key);if(ei.fd_touch > 0)close(ei.fd_touch);initEVT = 0;return 0;}int EVT_touch(int action, float x, float y){int abs_x, abs_y;if(initEVT == 0){LOGE("event not inital");return -1;}switch(action){case ACTION_DOWN:calculateXY(x, y, &abs_x, &abs_y);write_event(ei.fd_touch, 3, 0, abs_x);write_event(ei.fd_touch, 3, 1, abs_y);write_event(ei.fd_touch, 1, 330, 1);write_event(ei.fd_touch, 0, 0, 0);break;case ACTION_UP:write_event(ei.fd_touch, 1, 330, 0);write_event(ei.fd_touch, 0, 0, 0);break;case ACTION_MOVE:calculateXY(x, y, &abs_x, &abs_y);write_event(ei.fd_touch, 3, 0, abs_x);write_event(ei.fd_touch, 3, 1, abs_y);write_event(ei.fd_touch, 0, 0, 0);break;}return 0;}int EVT_key(int action, int key){if(initEVT == 0){LOGE("event not inital");return -1;}switch(action){case ACTION_DOWN:write_event(ei.fd_key, 1, key, 1);break;case ACTION_UP:write_event(ei.fd_key, 1, key, 0);break;}return 0;}int scan_dir(const char *dirname){char devname[PATH_MAX];char *filename;DIR *dir;struct dirent *de;dir = opendir(dirname);if(dir == NULL)return -1;strcpy(devname, dirname);filename = devname + strlen(devname);*filename++ = '/';while((de = readdir(dir))) {if(de->d_name[0] == '.' && (de->d_name[1] == '\0' ||(de->d_name[1] == '.' && de->d_name[2] == '\0')))continue;strcpy(filename, de->d_name);open_dev(devname);}closedir(dir);return 0;}int open_dev(const char *deviceName){int fd;int version;uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];fd = open(deviceName, O_RDWR);if(fd < 0) {LOGI("could not open device[%d]: %s", errno, strerror(errno));return -1;}if(ioctl(fd, EVIOCGVERSION, &version)) {return -1;}memset(key_bitmask, 0, sizeof(key_bitmask));if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))|| containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),sizeof_bit_array(BTN_DIGI))|| containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),sizeof_bit_array(KEY_MAX + 1))) {ei.fd_key = fd;LOGI("get key input device: %s", deviceName);}}memset(abs_bitmask, 0, sizeof(abs_bitmask));if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {// Is this a new modern multi-touch driver?if (test_bit(ABS_MT_POSITION_X, abs_bitmask)&& test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {ei.fd_touch = fd;LOGI("get multi-touch input device: %s", deviceName);// Is this an old style single-touch driver?} else if (test_bit(BTN_TOUCH, key_bitmask)&& test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {ei.fd_touch = fd;LOGI("get single-touch input device: %s", deviceName);}}}int write_event(int fd, int type, int code, int value){struct input_event event;memset(&event, 0, sizeof(event));event.type = type;event.code = code;event.value = value;if(write(fd, &event, sizeof(event)) < sizeof(event)) {LOGI("write event failed[%d]: %s", errno, strerror(errno));return -1;}return 0;}void calculateXY(float x, float y, int *abs_x, int *abs_y){*abs_x = ei.abs_x_min +(int)((x * (float)(ei.abs_x_max - ei.abs_x_min)) / ei.screen_width + 0.5);*abs_y = ei.abs_y_min +(int)((y * (float)(ei.abs_y_max - ei.abs_y_min)) / ei.screen_height + 0.5);}int containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex){ const uint8_t* end = array + endIndex; array += startIndex; while (array != end) { if (*(array++) != 0) { return 1; } } return 0;}
- android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
- android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
- android模拟按键问题总结[使用IWindowManager.injectKeyEvent方
- IWindowManager.injectKeyEvent模拟按键
- IWindowManager.injectKeyEvent模拟按键
- Android 实现模拟按键方法
- Android API中隐藏的类使用(例如IWindowManager)
- 【android】android使用命令模拟按键
- Android 实现模拟按键方法一
- Android 实现模拟按键方法一
- Android 实现模拟按键方法二
- Android 实现模拟按键方法一
- android jni方法模拟高频按键点击
- 关于使用VC模拟按键的问题
- android 软按键 模拟按键
- android 模拟按键
- android 应用模拟按键
- android 模拟按键
- 如何使用 Pylint 来规范 Python 代码风格
- cgi && fastcgi && php-fpm
- CpuInfo
- VM Ubuntu12.04 samba
- python 不是内部或外部命令
- android模拟按键问题总结[使用IWindowManager.injectKeyEvent方法]
- Nginx防攻击工具教程一 ngx_http_limit_conn_module
- Hibernate Annotations 中英文注解
- jquery动态添加option示例
- linux驱动开发--字符设备:添加文件指针偏移的功能
- 一些概念
- 字符串匹配的Boyer-Moore算法实现
- openbravo-3.0MP30-vmware-i386.vmdk 转移至esxi5.0
- 关于C++,VC++.Net和C#.Net混合编程中系统库(System32目录中动态库)引用问题