android uinput 按键_android 使用uinput模拟输入设备的方法

在google remote中,android接收端接收socket发来的IR CODE,然后将IR CODE模拟出来发给系统处理,这就是google remote接收端的原理。

系统端怎样模拟input event呢?

方法一:通过Instrumentation.sendKeyDownUpSync 实现,简单使用但是问题在于sendKeyDownUpSync发出的event,无法运行到

interceptKeyBeforeDispatching,也就无法正常作用 HOME,VOL...

方法二:通过uinput桥接;原理是利用内核现有的uinput驱动,通过内核驱动uinput来发送input event,而且还容易使用kl,kcm 客制化;

经过比较方法二较优,下面就就给出方法二的测试代码...

1、main函数,setup_uinput_device 完成设备的注册,然后创建一个线程 VirtualInputDev_EventThread,该线程重复发出keycode;

int main()

{

printf("Enter process !!!! \n");

stVirtualInputDevData *pKpdData = (stVirtualInputDevData*) malloc(sizeof(stVirtualInputDevData));

pKpdData->min_keycode = umin_keycode;

pKpdData->max_keycode = umax_keycode;

if (setup_uinput_device(pKpdData) < 0) {

printf("Unable to find uInput device\n");

free(pKpdData);

return -1;

}

pthread_attr_t attr;

pthread_attr_init(&attr);

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

if (0 != pthread_create(&keypad_EventThreadId, &attr, VirtualInputDev_EventThread, (void *)0)) {

printf("Create KeypadEventThread Failed!!\n");

exit(1);

}

// Coverity server need set to ignore this.

while (1) {

usleep(1000000);  // sleep 1 second

}

free(pKpdData);

pKpdData = 0;

// Destroy the device

ioctl(uinp_fd, UI_DEV_DESTROY);

close(uinp_fd);

return 0;

}

2、setup_uinput_device函数,完成设备注册;可以看到是直接打开uinput节点,设置了虚拟设备的name,verdor,product,bustype,

最后通过ioctl(uinp_fd, UI_DEV_CREATE)注册设备

int setup_uinput_device(stVirtualInputDevData* mstVirtualInputDevData)

{

struct uinput_user_dev uinp; // uInput device structure

int i;

// Open the input device

uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);

if (uinp_fd == 0) {

printf("Unable to open /dev/uinput\n");

return -1;

}

// Intialize the uInput device to NULL

memset(&uinp, 0x00, sizeof(uinp));

strncpy(uinp.name, "virtualinputdev", sizeof(uinp.name)-1);

uinp.id.vendor = 0x1341;

uinp.id.product = 0x0001;

uinp.id.bustype = BUS_VIRTUAL;

// Keyboard

ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);

for (i = mstVirtualInputDevData->min_keycode; i < mstVirtualInputDevData->max_keycode; i++) {

ioctl(uinp_fd, UI_SET_KEYBIT, i);

}

// Create input device into input sub-system

if (write(uinp_fd, &uinp, sizeof(uinp)) != sizeof(uinp)) {

printf("First write returned fail.\n");

return -1;

}

if (ioctl(uinp_fd, UI_DEV_CREATE)) {

printf("ioctl UI_DEV_CREATE returned fail.\n");

return -1;

}

return 1;

}

3、线程 VirtualInputDev_EventThread,只是重复发key,发key是通过write_event_to_device来完成的

static void* VirtualInputDev_EventThread(void *driver_data)

{

unsigned char u8Keycode,i=umin_keycode;

while (1) {

u8Keycode = 0xff;

/* sleep an interval time */

usleep(2000000);//sleep 5 s

/* fill event to uinput device. */

write_event_to_device(i++, 0);

if(i==4){

i = 0;

}

printf ("virtualinputdev thread ...\n");

//i %= umax_keycode;

}

printf ("virtualinputdev thread died\n");

pthread_exit(0);

return 0;

}

4、write_event_to_device 写event到uinput节点

void write_event_to_device(unsigned char u8KeyCode, unsigned char u8Repeat)

{

struct input_event event; // Input device structure

struct timespec s;

s.tv_nsec = 5000000L;

s.tv_sec = 0;

memset(&event, 0x00, sizeof(event));

gettimeofday(&event.time, 0);

event.type = EV_KEY;

event.code = u8KeyCode;

event.value = 1;

write(uinp_fd, &event, sizeof(event));

memset(&event, 0x00, sizeof(event));

gettimeofday(&event.time, 0);

event.type = EV_KEY;

event.code = u8KeyCode;

event.value = 0;

write(uinp_fd, &event, sizeof(event));

memset(&event, 0x00, sizeof(event));

gettimeofday(&event.time, 0);

event.type = EV_SYN;

event.code = SYN_REPORT;

event.value = 0;

write(uinp_fd, &event, sizeof(event));

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

绩效从C到S,分享渣渣程序员逆袭秘诀!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删绩效面谈结束&#xff0c;从会议室出来&#xff0c;有一种不真实的感觉——这个季度我竟然拿了S&#xff1f;&#xff01;要知道&#xff0c;上个…

海贼王为什么画风突变_什么是突变测试?

海贼王为什么画风突变最近&#xff0c;我再三提到突变测试一词。 因为可以说这种方法能够以超出代码覆盖范围的方式检测测试安全网的空白&#xff0c;所以我花了一些时间来追赶这个话题并尝试一下。 这篇文章总结了我的发现&#xff0c;作为对该主题的快速介绍。 什么是变异测…

C语言 #define 与 typedef 的区别与用法

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删在C语言编程中&#xff0c;typedef 和 #define是最常用语句&#xff0c;可能很多工作过几年的工程师都没有去深究过它们的一些用法和区别。typed…

spring总结_Spring综合课程总结

spring总结本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转换器和适…

合工大850参考书_合肥工业大学计算机考研850上岸经验分享

转载于 王道论坛 原作者 欲把西湖比西子 链接经验杂谈专业课考研&#xff0c;我个人认为主要还是考察基本的概念&#xff0c;以教材为主&#xff0c;教材就是圣经。不可否认&#xff0c;教材是枯燥的&#xff0c;尤其像数据结构这样的课程&#xff0c;比较抽象&#xff0c;就算…

硬核!400 行代码实现一个虚拟机

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删我们都知道理工科类的大学专业&#xff0c;一般都会在大一选择教授 C 语言作为编程入门语言&#xff0c;我最初接触编程也是入的 C 语言的坑。课…

23种设计模式简介_设计模式简介

23种设计模式简介本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &am…

python实现api接口的脚本_Zabbix批量添加主机,Python调用api接口方式【脚本定制】...

使用说明&#xff1a;此脚本使用方法&#xff0c;详细步骤如下(不清楚的可以加我微信或QQ咨询)脚本默认添加内容如excel模板所示&#xff1a;主机名、显示名、IP地址、所属组、所属模板1、所属模板2(如需要添加其他内容如: 多个所属组、多个模板、DNS、SNMP等&#xff0c;可联系…

Spring集成基础知识

本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转换器和适配器。 在这…

C++最佳实践 | 工具

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删前言C最佳实践: 支持Fork的编码标准文档本文档旨在收集对C最佳实践所进行的协作性讨论&#xff0c;是《Effective C》(Meyers) 和《C Coding Sta…

python resize_Python resize

最新项目flask扩展&#xff0c;用于自动调整代码中图像的大小&#xff0c;以及模板。可以从JPEG PNG SVG转换为JPEG PNG&#xff0c;调整大小以适应和裁剪。提供基于文件和基于s3的存储选项。有关文档&#xff0c;请参见https: ...2020-12-22已阅读: n次django resizer允许动态…

C语言函数返回 1 和返回 0 哪个好?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删基本上&#xff0c;没有人会将大段的C语言代码全部塞入 main() 函数。更好的做法是按照复用率高、耦合性低的原则&#xff0c;尽可能的将代码拆分…

抽象工厂和工厂方法示例_抽象工厂设计模式示例

抽象工厂和工厂方法示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查…

人脸识别像素最低_一种低分辨率图像的人脸识别方法与流程

本发明涉及计算机视觉技术领域&#xff0c;更具体地&#xff0c;涉及一种低分辨率图像的人脸识别方法。背景技术&#xff1a;目前最常用的人脸识别算法是基于卷积神经网络(Convolutional Neural Network&#xff0c;CNN)的&#xff0c;CNN由一系列的卷积操作组成&#xff0c;如…

史上最污技术解读,我竟然秒懂了

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删假设你是个妹子&#xff0c;你有一位男朋友&#xff0c;于此同时你和另外一位男生暧昧不清&#xff0c;比朋友好&#xff0c;又不是恋人。你随时…

textureview 缩放_View的双指缩放以及移动

最近做项目&#xff0c;做到了要让视频缩放的功能&#xff0c;所以写了一个小DEMO&#xff0c;进行双指手势的操作&#xff0c;DEMO是使用TextView做测试&#xff0c;实际使用监听放在TextureView也是正常运行。首先就是记录下触摸屏幕的手指数量&#xff0c;一个手指触摸的时候…

tdd java_Java TDD简介–第1部分

tdd java欢迎来到测试驱动开发 &#xff08;TDD&#xff09;系列的介绍。 我们将在TDD上下文中讨论Java和JUnit &#xff0c;但这只是工具。 本文的主要目的是使您全面了解TDD&#xff0c;而无论使用哪种编程语言和测试框架。 如果您在项目中不使用TDD&#xff0c;那么您要么是…

C++最佳实践 | 代码风格

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删C最佳实践:1. 工具2. 代码风格&#xff08;本文&#xff09;3. 安全性4. 可维护性5. 可移植性及多线程6. 性能7. 正确性和脚本代码风格代码风格最…

使用map的find头文件_C++ map用法

C 中 map 提供的是一种键值对容器&#xff0c;里面的数据都是成对出现的,如下图&#xff1a;每一对中的第一个值称之为关键字(key)&#xff0c;每个关键字只能在 map 中出现一次&#xff1b;第二个称之为该关键字的对应值。在一些程序中建立一个 map 可以起到事半功倍的效果&am…

lucene 查询示例_高级Lucene查询示例

lucene 查询示例本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中&#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要&#xff0c;然后了解Lucene中搜索的工作方式。 此外&#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中…