在Android上使用/dev/uinput时,单击错误的位置
我的项目的功能看起来像。但有点不同。 我有一个在Android上运行的服务器程序和一个在PC上运行的客户端。我想通过在PC上操作来控制手机 这个项目的大部分工作已经完成,但在控制步骤中发生了一点错误。也许你知道我们一直 用于实现对操作命令的响应目标 从PC客户端。我在编写这部分程序时参考了其他人。另外,我是Android新手,所以有些事情超出了我的控制范围 好的,我会告诉你下面的细节。 例如,当您单击鼠标或按下PC上的某些键时,服务器通过某些协议(如)接收此命令 ,并获取有关命令事件的相关信息,例如按钮掩码(可以决定向左或向右) 鼠标右键单击)或位置(X、Y坐标)。按照以下三个步骤向Android发送命令 首先,通过android中“/dev/uinput”的开放设备创建输入设备。 其次,向输入子系统注入相关事件。 然后,将事件写入虚拟输入子系统 简化代码:在Android上使用/dev/uinput时,单击错误的位置,android,Android,我的项目的功能看起来像。但有点不同。 我有一个在Android上运行的服务器程序和一个在PC上运行的客户端。我想通过在PC上操作来控制手机 这个项目的大部分工作已经完成,但在控制步骤中发生了一点错误。也许你知道我们一直 用于实现对操作命令的响应目标 从PC客户端。我在编写这部分程序时参考了其他人。另外,我是Android新手,所以有些事情超出了我的控制范围 好的,我会告诉你下面的细节。 例如,当您单击鼠标或按下PC上的某些键时,服务器通过某些协议(如)接收此命令 ,并获取有关命令事件的相关信息,
//First ADN SECOND STEPS:
int initial()
{
int inputfd = -1;
uinput_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
/* Set device to handle following types of events: */
/* Key and button repetition events */
if (ioctl(uinput_fd, UI_SET_EVBIT, EV_REP) == -1)
return -1;
/* Absolute pointer motions */
if (ioctl(uinput_fd, UI_SET_EVBIT, EV_ABS) == -1)
return -1;
/* Configure device to handle absolute x and y axis. */
if (ioctl(uinput_fd, UI_SET_ABSBIT, ABS_X) == -1)
goto err;
if (ioctl(uinput_fd, UI_SET_ABSBIT, ABS_Y) == -1)
return -1;
/* Synchronization events, this is probably set implicitely too. */
if (ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN) == -1)
return -1;
struct uinput_user_dev user_dev;
/* Set device-specific information. */
memset(&user_dev, 0, sizeof(user_dev));
strncpy(user_dev.name, device_name, UINPUT_MAX_NAME_SIZE);
user_dev.id.bustype = BUS_USB;
user_dev.id.vendor = 1;
user_dev.id.product = 1;
user_dev.id.version = 1;
//minor tweak to support ABSolute events
user_dev.absmin[ABS_X] = 0;
user_dev.absmax[ABS_X] = 799;
user_dev.absfuzz[ABS_X] = 0;
user_dev.absflat[ABS_X] = 0;
user_dev.absmin[ABS_Y] = 0;
user_dev.absmax[ABS_Y] = 479;
user_dev.absfuzz[ABS_Y] = 0;
user_dev.absflat[ABS_Y] = 0;
if (write(uinput_fd, &user_dev, sizeof(user_dev)) != sizeof(user_dev))
return -1;
if (ioctl(uinput_fd, UI_DEV_CREATE) == -1)
return -1;
}
//THREE STEP:
//call by ptrEvent
int suinput_write(int uinput_fd, uint16_t type, uint16_t code, int32_t value)
{
struct input_event event, nullevent;
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, 0); /* This should not be able to fail ever.. */
event.type = type;
event.code = code;
event.value = value;
if (write(uinput_fd, &event, sizeof(event)) != sizeof(event))
return -1;
return 0;
}
//begin to deal with event
void ptrEvent(int buttonMask, int x, int y, rfbClientPtr cl)
{
static int leftClicked=0;
if ( inputfd == -1 )
return;
if (buttonMask & 1)
{ //left btn clicked
leftClicked=1;
suinput_write(inputfd, EV_ABS, ABS_X, x);
suinput_write(inputfd, EV_ABS, ABS_Y, y);
suinput_write(inputfd,EV_KEY,BTN_TOUCH,1);
suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
}
else if (leftClicked)
{ //left btn released
leftClicked=0;
suinput_write(inputfd, EV_ABS, ABS_X, x);
suinput_write(inputfd, EV_ABS, ABS_Y, y);
suinput_write(inputfd,EV_KEY,BTN_TOUCH,0);
suinput_write(inputfd, EV_SYN, SYN_REPORT, 0);
}
}
Android设备的分辨率为800*480。客户端图片也有相同的大小。我调试了上面的代码,发现
服务器从事件消息接收正确的位置。在ptrEvent函数中,X和Y正好对应于实数
点击位置出现在PC上。但从Android上显示的实际按下位置来看,有一个不同的位置。如你所见,
我将Android虚拟输入设备的最大绝对范围设置为与实际分辨率相同,因此客户端和服务器之间显然没有偏差
坐标为什么会发生这种情况?
对应于电脑中出现的实际点击位置。
。你认为真正的点击位置是什么?是根据照片的一角画的吗?以与其决议相同的单位?所以这张图片是800*480,位置是400240你指中间吗?@greenapps是的,我在“ptrEvent”功能中打印出x和y。我不确定这是一个非常敏锐的坐标,但从大致位置看,它是正确的。例如,我点击图片三次,然后点击左上角、右上角和右下角,打印出(10,20)、(760,20)、(760754)。从中我们可以看出,该坐标系以左上角为参考,相对于800*400的实际分辨率可能是正确的。所以如果我在中间点击,它会得到(400240)。与分辨率相同的单位是什么意思?与分辨率相同的单位
。如果分辨率为800*480的图片被缩放为600*360。如果你说“我点击了400280位置,那你是什么意思?但我还是不明白你的问题。你发布了很多代码来传递一些值。但转移是否存在问题?计算一些偏移量和相应的坐标不是更重要吗?