android 使用uinput模擬輸入設(shè)備的方法
在google remote中,android接收端接收socket發(fā)來的IR CODE,然后將IR CODE模擬出來發(fā)給系統(tǒng)處理,這就是google remote接收端的原理。
系統(tǒng)端怎樣模擬input event呢?
方法一:通過Instrumentation.sendKeyDownUpSync 實(shí)現(xiàn),簡單使用但是問題在于sendKeyDownUpSync發(fā)出的event,無法運(yùn)行到
interceptKeyBeforeDispatching,也就無法正常作用 HOME,VOL...
方法二:通過uinput橋接;原理是利用內(nèi)核現(xiàn)有的uinput驅(qū)動(dòng),通過內(nèi)核驅(qū)動(dòng)uinput來發(fā)送input event,而且還容易使用kl,kcm 客制化;
經(jīng)過比較方法二較優(yōu),下面就就給出方法二的測(cè)試代碼...
1、main函數(shù),setup_uinput_device 完成設(shè)備的注冊(cè),然后創(chuàng)建一個(gè)線程 VirtualInputDev_EventThread,該線程重復(fù)發(fā)出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函數(shù),完成設(shè)備注冊(cè);可以看到是直接打開uinput節(jié)點(diǎn),設(shè)置了虛擬設(shè)備的name,verdor,product,bustype,
最后通過ioctl(uinp_fd, UI_DEV_CREATE)注冊(cè)設(shè)備
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,只是重復(fù)發(fā)key,發(fā)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節(jié)點(diǎn)
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));
}
- Android中的windowSoftInputMode屬性詳解
- Android WebView 不支持 H5 input type="file" 解決方法
- Android 數(shù)據(jù)存儲(chǔ)之 FileInputStream 工具類及FileInputStream類的使用
- Android編程開發(fā)之EditText中inputType屬性小結(jié)
- Android WebView支持input file啟用相機(jī)/選取照片功能
- Android網(wǎng)頁H5 Input選擇相機(jī)和系統(tǒng)相冊(cè)
- 詳解Android WebView的input上傳照片的兼容問題
- Android自定義PasswordInputView密碼輸入
- Android InputMethodManager輸入法簡介
- 從"Show?tabs"了解Android?Input系統(tǒng)
相關(guān)文章
詳解Android10的分區(qū)存儲(chǔ)機(jī)制(Scoped Storage)適配教程
這篇文章主要介紹了詳解Android10的分區(qū)存儲(chǔ)機(jī)制(Scoped Storage)適配教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Android實(shí)現(xiàn)文件下載進(jìn)度顯示功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)文件下載進(jìn)度顯示功能,檢測(cè)Android文件下載進(jìn)度,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02Android編程實(shí)現(xiàn)懸浮窗獲取并顯示當(dāng)前內(nèi)存使用量的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)懸浮窗獲取并顯示當(dāng)前內(nèi)存使用量的方法,涉及Android針對(duì)窗口及內(nèi)存的相關(guān)操作技巧,需要的朋友可以參考下2017-07-07Kotlin中l(wèi)et()with()run()apply()also()函數(shù)的使用方法與區(qū)別
在Kotlin中的源碼標(biāo)準(zhǔn)庫(Standard.kt)中提供了一些Kotlin擴(kuò)展的內(nèi)置函數(shù)可以優(yōu)化kotlin的編碼,今天為大家聊聊let,with,run,apply,also幾個(gè)函數(shù)的用法與區(qū)別2018-03-03Android 實(shí)現(xiàn)圖片轉(zhuǎn)二進(jìn)制流及二進(jìn)制轉(zhuǎn)字符串
這篇文章主要介紹了Android 實(shí)現(xiàn)圖片轉(zhuǎn)二進(jìn)制流及二進(jìn)制轉(zhuǎn)字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03android音樂播放簡單實(shí)現(xiàn)的簡單示例(MediaPlayer)
本篇文章主要介紹了android音樂播放簡單實(shí)現(xiàn)的簡單示例(MediaPlayer),具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08Android顯示網(wǎng)絡(luò)圖片實(shí)例
這篇文章主要介紹了Android顯示網(wǎng)絡(luò)圖片的方法,以實(shí)例形式展示了Android程序顯示網(wǎng)絡(luò)圖片的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10Android之禁止ViewPager滑動(dòng)實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了Android之禁止ViewPager滑動(dòng)實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05