说说android下TV版本UC浏览器模拟鼠标的实现 无意中下载了一个TV版本的UC浏览器安装到机顶盒上,顺便体验了一把。感觉吗还行,原先以为UC浏览器会针对Android下TV的遥控器操作浏览网页会做出一些优化或者对网页做出一些重新编码什么的,但是结果不是原来是通过遥控器控制然后在Android下TV端模拟鼠标操作。 说到Android下模拟鼠标操作,想到我以前也做过这么一个项目就是在手机端开发一个客户端然后模拟鼠标操作Android下的TV,这个也是类似于TV版本的UC浏览器的操作方式。实现该功能的原理就是通过在linux下模拟按键和鼠标
输入(因为Android是跑在linux下的所以该原理也是同样适合的)。至于原理我这里就不多介绍了,感兴趣的朋友可以到网上查找查找,我这里为了节约大家的时间贴出了一篇
http://blog.csdn.net/chenzhixin/article/details/2173530
现在进入正题,既然是通过在linux下模拟按键和鼠标输入,但是Android是java语言开发的怎么才能调用到linux层去呢,大家可能想到了我们可以通过JNI调用到底层啊。是的,我这里也是这么实现的。看来JNI确实是一个好东西啊!Android下对于JNI的注册有两种方法,一种是静态注册一种是动态注册,其中在Android的源码中采用的比较多的是动态注册。关于这两种注册方式我在这里就不多做罗列了。我这里采用的是第一种方法静态注册,先来看看我这里提供的本地方法,如下所示:
/ **************************************** * @author Administrator *功能:通过jni调用实现远程模拟鼠标功能 ***************************************/ public class MouseUtils { public native void mouse_clck(int type, int code , int value);//鼠标点击 public native void mouse_move(int type, int code , int value);//鼠标点击 public native void mouse_open();//打开鼠标 public native void mouse_close();//关掉鼠标 }

那么接下来的重点就是通过C语言来实现这些本地方法了,至于在Android层何时调用这些方法那就是业务层的
事了,下面的代码就是我用C语言实现的上述本地方法了,其中的input.h和uinput.h可以在linux下找到,这里我就不放在上面了。
#include<stdio.h> #include<jni.h> #include"com.coship.coshare.domain.MouseUtils.h" #include <android/log.h> #include<malloc.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include "input.h" #include "uinput.h" #define die(str, args...) do { perror(str); exit(EXIT_FAILURE); } while(0); #define LOG_TAG "System.out.c" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) int fd; struct uinput_user_dev uidev; // uInput device structure JNIEXPORT void JNICALL Java_com_coship_coshare_domain_MouseUtils_mouse_1clck (JNIEnv * env, jobject obj , jint type, jint code , jint value ) { simulate_mousesingleclick(fd); } JNIEXPORT void JNICALL Java_com_coship_coshare_domain_MouseUtils_mouse_1move (JNIEnv *env, jobject obj , jint type , jint value_x , jint value_y) { simulate_mouse(fd, value_x, value_y); } JNIEXPORT void JNICALL Java_com_coship_coshare_domain_MouseUtils_mouse_1open (JNIEnv *env, jobject obj) { fd = setup_uinput_device(); if(fd <= 0) { LOGI("error open keyboard:\n"); return; } } JNIEXPORT void JNICALL Java_com_coship_coshare_domain_MouseUtils_mouse_1close (JNIEnv *env, jobject obj) { close_mouse_device(); } void close_mouse_device() { close(fd); } void simulate_mouse(int fd, int value_x, int value_y) { struct input_event event; memset(&event, 0, sizeof(event)); gettimeofday(&event.time, NULL); event.type = EV_REL; event.code = REL_X; event.value = value_x; write(fd, &event, sizeof(event)); event.type = EV_REL; event.code = REL_Y; event.value = value_y; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); } /****************************************** 模拟鼠标点击 *****************************************/ void simulate_mousesingleclick(int fd) { struct input_event event; memset(&event, 0, sizeof(event)); gettimeofday(&event.time, NULL); event.type = EV_KEY; event.code = BTN_LEFT; event.value = 1; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); event.type = EV_KEY; event.code = BTN_LEFT; event.value = 0; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); } /*************************** 打开鼠标 ***************************/ int setup_uinput_device() { int i=0; // Open the input device fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); if(fd < 0) { die("error: open /dev/uinput"); } memset(&uidev, 0, sizeof(uidev)); // Intialize the uInput device to NULL snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-Openkk"); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x1; uidev.id.product = 0x1; uidev.id.version = 1; // Setup the driver I/O channels ioctl(fd, UI_SET_EVBIT, EV_KEY); ioctl(fd, UI_SET_KEYBIT, BTN_LEFT); for (i=0; i < 256; i++) { ioctl(fd, UI_SET_KEYBIT, i); } ioctl(fd, UI_SET_EVBIT, EV_REL); ioctl(fd, UI_SET_RELBIT, REL_X); ioctl(fd, UI_SET_RELBIT, REL_Y); /* Create input device into input sub-system */ write(fd, &uidev, sizeof(uidev)); if(ioctl(fd, UI_DEV_CREATE) < 0) { die("error: create uinput device"); LOGI("error: create uinput device"); } return fd; }

如上就是在Android下实现模拟鼠标的简单思路了,至于怎么将手机客户端的相关命令发送到Android下的TV端然后再模拟鼠标这个的方法就老多了,譬如可以通过网络啊通过蓝牙啊。这些东西就不在我讨论的范围之内了。我这里只是提供了一个简单思路。

更多相关文章

  1. android实现观察者模式的几种方法
  2. Android Studio怎样提示函数使用方法
  3. 【Android 性能优化】应用启动优化 ( 安卓应用启动分析 | Launch
  4. Android方法数
  5. 改变Android按钮背景颜色的高效方法
  6. Android 横向ScrollView照片浏览器实现
  7. Android双击返回键退出程序的实现方法
  8. 混合开发之ReactNative调用Android原生方法

随机推荐

  1. Android模拟器RAM修改方法 - 尤其是3.0
  2. Android(安卓)SDK Manager无法显示可供下
  3. 安装Android的Eclipse插件ADT遇到错误“r
  4. Android中添加Admob广告
  5. Android(安卓)手机震动调用
  6. 在Android(安卓)Studio 中使用ADB命令模
  7. Android(安卓)ViewPager使用详解
  8. Android(安卓)HAL模块实现
  9. android多线程断点下载——网络编
  10. Android中使用加速度传感器