android - Uinput虚拟设备在android上被检测为物理键盘

标签 android user-input linux-device-driver

我用 C 语言创建了一个简单的 native 库,允许用户使用 uinput 模块创 build 备。代码似乎可以工作,但是有一个问题: 我的虚拟设备被检测为物理键盘,当我需要写一些文本时,软键盘不会出现,因为 android 检测到连接了一个真实的键盘。

如何将此设备设置为虚拟?如果我不设置键位,则不会将其检测为物理键盘,但我需要启用这些键。

#include <string.h>
#include <jni.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "input.h"
#include "uinput.h"

static int fd;
static struct uinput_user_dev dev;


jint Java_com_vektor_amapper_util_InputDeviceManager_CreateVirtualDevice(
    JNIEnv* env, jobject thiz, jstring param) {
int aux;
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if (fd < 0)
    return -1;
if (ioctl(fd, UI_SET_EVBIT, EV_KEY)<0)
        return -2;
if (ioctl(fd, UI_SET_EVBIT, EV_REL)<0)
    return -3;
if (ioctl(fd, UI_SET_EVBIT, EV_ABS)<0)
    return -4;
if (ioctl(fd, UI_SET_EVBIT, EV_SYN)<0)
    return -5;
if (ioctl(fd, UI_SET_EVBIT, EV_REP)<0)
    return -6;

    for(aux = KEY_1; aux <= KEY_F10; aux++){
    if(ioctl(fd,UI_SET_KEYBIT,aux)!=0) return -10;
}

ioctl(fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(fd, UI_SET_KEYBIT, BTN_TOUCH);
    ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(fd, UI_SET_KEYBIT, BTN_BACK);

    ioctl(fd, UI_SET_RELBIT, REL_X);
ioctl(fd, UI_SET_RELBIT, REL_Y);

ioctl (fd, UI_SET_ABSBIT, ABS_X);
ioctl (fd, UI_SET_ABSBIT, ABS_Y);
    ioctl (fd, UI_SET_ABSBIT, ABS_Z);

ioctl (fd, UI_SET_ABSBIT, ABS_RX);
ioctl (fd, UI_SET_ABSBIT, ABS_RY);
ioctl (fd, UI_SET_ABSBIT, ABS_RZ);


    memset(&dev, 0, sizeof(dev));
const char *cparam = (*env)->GetStringUTFChars(env, param, 0);
snprintf(dev.name, UINPUT_MAX_NAME_SIZE, cparam);
(*env)->ReleaseStringUTFChars(env, param, cparam);
dev.id.bustype = BUS_VIRTUAL;
dev.id.vendor = 0x1234;
dev.id.product = 0xFEDC;
dev.id.version = 1;

    if (write(fd, &dev, sizeof(dev)) < 0)
    return -7;

if (ioctl(fd, UI_DEV_CREATE) < 0)
        return -8;

return 0;

}

jint Java_com_vektor_amapper_util_InputDeviceManager_DestroyVirtualDevice(
    JNIEnv* env, jobject thiz) {
if (ioctl(fd, UI_DEV_DESTROY) < 0)
    return -1;
close(fd);
return 0;
}

最佳答案

为了解决这个问题,我制作了自定义 IME: 我从 com.example.android.softkeyboard 包中获取了 SoftKeyboard 然后要做的就是简单地覆盖 onEvaluateInputViewShown 方法:

@Override
public boolean onEvaluateInputViewShown() {
    return true;
}

关于android - Uinput虚拟设备在android上被检测为物理键盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16979532/

相关文章:

validation - 验证用户输入是否符合混合大小写要求

c - IOCTL 调用无法读取和写入设备

python - 从 Pandas Dataframe 中的文本文件获取用户输入

不带序列化的 Java 深度复制

android - 为 UsbDeviceConnection 设置波特率

javascript - 代码 :1000 Can't write or create a file in my app using ionic-native/file ionic 2

c - 如何一次输入二维字符串的所有元素?

linux - linux/proc/tty/drivers 中没有 VT 驱动程序

c - C 中的函数模拟?

java - Android(Archos 5 IT)上的音频(MediaPlayer)