说说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(安卓)自定义View实现竖直跑马灯效果
  2. Android(安卓)App 启动流程梳理(基于 Android(安卓)10)
  3. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)
  4. 在Android中实现Hook机制的实验
  5. Android从启动到程序运行发生的事情
  6. Android学习建议
  7. 在Android中监控来电和去电
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android热补丁动态修复技术(完结篇):自动
  2. 使用TensorFlow在Android上进行物体检测
  3. 飞凌ok6410开发板 android 有线配置
  4. Error:Could not find com.android.tools
  5. Android常用到得方法积累
  6. Android NDK开发使用以及so文件生成和注
  7. android与html5的交互——数据库操作,UI操
  8. Android源码分析之WindowManager.LayoutP
  9. android googleMap使用并在指定的位置上
  10. Google Android开发精华教程