第一章 模拟按键:
文章目录
- 安卓系列
- 远程办公需求之远程遥控
- 一、远程遥控是什么?
- 二、实现方案
- 1.通讯实现
- 2.底层调用
- 总结
远程办公需求之远程遥控
2021-10,最近因为新疆,甘肃等疫情,远程办公需求又一次收到刺激,最近公司在搭建远程办公环境,对于某些产品需要进行遥控控制操作,来实现问题定位与解决。接手了一个模拟遥控的任务
一、远程遥控是什么?
远程遥控实际上是一个控制软件,作为服务端来接收客户端的指令,并且通过调用按键事件来实现对中服务端所在的硬件进行相应遥控操作。服务端通过绑定端口地址,等待客户端的连接,然后接收按键,并解析按键,处理对应按键,调用sendevent事件来操作。
二、实现方案 1.通讯实现控制通过使用socket来实现的,分为客户端和服务端,客户端为一个遥控器程序,python+qt5来实现界面和逻辑,服务端是一个运行程序,在被控制的终端上跑,在云桌面通过客户端模拟的键值按下,将socket消息发送给服务端,服务端根据接收到的消息,截取其中的按键位,取按键位并根据按键表映射到本端处理。
绑定服务:
int Serverbind(void)
{
int Res = -1;
int optVal = 1;
vctlog(LOG_LEVEL_DEBUG_T,"Info:Serverbind entern");
memset(&tserverinfo,0,sizeof(tserverinfo));
tserverinfo.socketAddr.sin_family = AF_INET;
tserverinfo.socketAddr.sin_port = htons(SIMULA_KEYBOARD_PORT); //57620
tserverinfo.cSocketId = socket(AF_INET, SOCK_STREAM, 0);
vctlog(LOG_LEVEL_DEBUG_T,"Info:Serverbind socket:%dn",tserverinfo.cSocketId);
if(tserverinfo.cSocketId < 0)
{
vctlog(LOG_LEVEL_DEBUG_T,"Error:Create serversocket error.n");
return Res;
}
//套接字设置:可重用端口
if ( setsockopt(tserverinfo.cSocketId, SOL_SOCKET, SO_REUSEADDR, (char*)&optVal, sizeof(optVal)) != 0)
{
vctlog(LOG_LEVEL_DEBUG_T,"Error:setsockopt fail.n");
goto EXIT;
}
if(bind(tserverinfo.cSocketId, (struct sockaddr *)&tserverinfo.socketAddr, sizeof(tserverinfo.socketAddr)) != 0)
{
vctlog(LOG_LEVEL_DEBUG_T, "Error:bind serversocket error: %sn",strerror(errno));
goto EXIT;
}
if (listen(tserverinfo.cSocketId, MAX_CONNECT_NUM) != 0)
{
vctlog(LOG_LEVEL_DEBUG_T, "Error:listen serversocket error: %sn",strerror(errno));
goto EXIT;
}
vctlog(LOG_LEVEL_DEBUG_T, "Info:ServerSocket end, bind port is %dn",SIMULA_KEYBOARD_PORT);
MaxSockSize = MAX(MaxSockSize, tserverinfo.cSocketId);
return tserverinfo.cSocketId;
EXIT:
close(tserverinfo.cSocketId);
vctlog(LOG_LEVEL_DEBUG_T, "Error:shut Serverbindn");
return Res;
}
映射表:
{ REMOTE_KEY_FIVE , ANDROID_KEY_FIVE , "'5'" },
{ REMOTE_KEY_SIX , ANDROID_KEY_SIX , "'6'" },
{ REMOTE_KEY_SEVEN , ANDROID_KEY_SEVEN , "'7'" },
{ REMOTE_KEY_EIGHT , ANDROID_KEY_EIGHT , "'8'" },
{ REMOTE_KEY_NINE , ANDROID_KEY_NINE , "'9'" },
2.底层调用
具体实现是调用get/sendevent来实现具体的按键操作,分为控制码按下,控制码抬起,以及一起发送的载体码。
底层操作:
int UpDownLeftRight(int keyvalue)
{
char cmdstr[128] = {0};
int keyraise = 1;
int i = 0;
if(22 == SdkVersion)
{
snprintf(cmdstr, sizeof(cmdstr), "%s %d %d %d", "sendevent /dev/input/event1",4,4,86);
system(cmdstr);
}
for(i=0;i<4;i++)
{
if((i+1)%2)
{
snprintf(cmdstr, sizeof(cmdstr), "%s %d %d %d", "sendevent /dev/input/event1",1,keyvalue,keyraise--);
}
else
{
snprintf(cmdstr, sizeof(cmdstr), "%s %d %d %d", "sendevent /dev/input/event1",0,0,0);
}
system(cmdstr);
}
return 0;
}
总结
之前调用的是/system/bin/input keyevent,这里发现调用这个事件会出现延迟很大,达到5.600ms,并且当光标陷入输入框的时候,无法通过上下左右键切换光标,很影响使用。



