当前位置: 首页 > news >正文

TV遥控器模拟鼠标键

需求 : tv上部分app不支持光标选中,如亚马逊,插上鼠标不方便,即可以用遥控器模拟鼠标滚动和点击

1.拦截上下左右键

在WMS::PhoneWindowManager::interceptKeyBeforeQueueing中监听上下左右左右键,进行拦截。

@Overridepublic long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {//是否开启鼠标模式String mstate = SystemProperties.get("sys.KeyMouse.mKeyMouseState");//是否开启鼠标滚轮模式String mMode = SystemProperties.get("sys.mouse.mousemode1");if (mstate.equals("on") && ((keyCode == KeyEvent.KEYCODE_DPAD_LEFT)|| (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)|| (keyCode == KeyEvent.KEYCODE_DPAD_UP)|| (keyCode == KeyEvent.KEYCODE_DPAD_DOWN))) {if(down){if (mMode.equals("false")) {try{// 显示鼠标键mWindowManager.dispatchMouse(0,0);}catch(Exception e){}} else {Message msg = new Message();msg.what = keyCode;Bundle bundle = new Bundle();bundle.putInt("repeatCount", repeatCount);msg.setData(bundle);mKeyMouseHandler.sendMessage(msg);}}return -1;}
}public Handler mKeyMouseHandler = new Handler(){public void handleMessage(Message msg){Bundle bundle = msg.getData();int repeatNum = bundle.getInt("repeatCount");switch(msg.what){case KeyEvent.KEYCODE_DPAD_LEFT:if(repeatNum>0){//移动的距离mdeltax=-16.0f;mdeltay=0;}else{mdeltax=-8.0f;mdeltay=0;}break;case KeyEvent.KEYCODE_DPAD_RIGHT://移动的距离if(repeatNum>0){mdeltax=16.0f;mdeltay=0;}else{mdeltax=8.0f;mdeltay=0;}break;case KeyEvent.KEYCODE_DPAD_UP://移动的距离if(repeatNum>0){mdeltax=0;mdeltay=-16.0f;}else{mdeltax=0;mdeltay=-8.0f;}break;case KeyEvent.KEYCODE_DPAD_DOWN://移动的距离if(repeatNum>0){mdeltax=0;mdeltay=16.0f;}else{mdeltax=0;mdeltay=8.0f;}break;case KeyEvent.KEYCODE_MOUSE_SWITCH://位置不变,重新显示mdeltax=0;mdeltay=0;break;    }try{mWindowManager.dispatchMouse(mdeltax,mdeltay);}catch(Exception e){}}};

2.调整鼠标滚动逻辑

如果只需要鼠标上下移动,上述修改即可,鼠标移动到屏幕周围会自动切为滚动模式,但是如果部分app上下有部分导航栏,即需要主动将鼠标切为滚轮模式。

修改位置 frameworks/native/services/inputflinger/InputReader.cpp

void KeyMouseInputMapper::sync(nsecs_t when) {int32_t lastButtonState = mButtonState;int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();mButtonState = currentButtonState;char *mKeyLock=new char[PROPERTY_VALUE_MAX];memset(mKeyLock,0,5);property_get("sys.KeyMouse.mKeyMouseState",mKeyLock,"off");char *mousemode=new char[PROPERTY_VALUE_MAX];memset(mousemode,0,5);property_get("sys.mouse.mousemode1",mousemode,"true");bool scrolled = 0;float vscroll,hscroll;int32_t keystate = AKEY_STATE_UNKNOWN;bool wasDown = isPointerDown(lastButtonState);bool down = isPointerDown(currentButtonState);keystate = getScanCodeState(AINPUT_SOURCE_MOUSE,scrollkey);bool downChanged;if (!wasDown && down) {mDownTime = when;downChanged = true;} else if (wasDown && !down) {downChanged = true;} else {downChanged = false;}nsecs_t downTime = mDownTime;//int32_t buttonsPressed=0;//int32_t buttonsReleased=0;int32_t buttonsPressed = currentButtonState & ~lastButtonState;int32_t buttonsReleased = lastButtonState & ~currentButtonState;if(strcmp(mKeyLock,"off")==0)  return;PointerProperties pointerProperties;pointerProperties.clear();pointerProperties.id = 0;pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;PointerCoords pointerCoords;pointerCoords.clear();int32_t displayId;if (mPointerController != NULL) {float x, y;float minX, minY, maxX, maxY;mPointerController->getPosition(&x, &y);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);displayId = ADISPLAY_ID_DEFAULT;//滚动模式后,判断上下左右键即滚动if(strcmp(mousemode,"false")==0) {if(scrollkey == KEY_LEFT){scrolled = 1;vscroll = 0;hscroll = -3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if(scrollkey == KEY_UP){scrolled = 1;vscroll = 3.0f;hscroll = 0;}else if(scrollkey == KEY_RIGHT){scrolled = 1;vscroll = 0;hscroll = 3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if(scrollkey == KEY_DOWN){scrolled = 1;vscroll = -3.0f;hscroll = 0;}}else{if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {if((x<=minX)&&(scrollkey == KEY_LEFT)){scrolled = 1;vscroll = 0;hscroll = -3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if((y<=minY)&&(scrollkey == KEY_UP)){scrolled = 1;vscroll = 3.0f;hscroll = 0;}else if((x>=maxX)&&(scrollkey == KEY_RIGHT)){scrolled = 1;vscroll = 0;hscroll = 3.0f;if(keystate==AKEY_STATE_DOWN)buttonsPressed = 1;elsebuttonsReleased = 1;}else if((y>=maxY)&&(scrollkey == KEY_DOWN)){scrolled = 1;vscroll = -3.0f;hscroll = 0;}}}}uint32_t policyFlags = 0;if ((buttonsPressed || scrolled) && getDevice()->isExternal()) {policyFlags |= POLICY_FLAG_WAKE;}mSource = AINPUT_SOURCE_MOUSE;// Send motion event.if (downChanged || scrolled) {int32_t metaState = mContext->getGlobalMetaState();int32_t buttonState = lastButtonState;int32_t motionEventAction;if (downChanged) {motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;} else  {motionEventAction = AMOTION_EVENT_ACTION_MOVE;}if (buttonsReleased) {BitSet32 released(buttonsReleased);while (!released.isEmpty()) {int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());buttonState &= ~actionButton;NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&releaseArgs);buttonsReleased = 0;}}NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,motionEventAction, 0, 0,metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, 0, 1, &pointerProperties, &pointerCoords, 1, 1, downTime);getListener()->notifyMotion(&args);if (buttonsPressed) {BitSet32 pressed(buttonsPressed);while (!pressed.isEmpty()) {int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());buttonState |= actionButton;NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&pressArgs);buttonsPressed = 0;}}}if ((scrolled)&&(keystate==AKEY_STATE_DOWN)) {pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);int32_t metaState = mContext->getGlobalMetaState();NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,AMOTION_EVENT_EDGE_FLAG_NONE,displayId, /* deviceTimestamp */ 0, 1, &pointerProperties, &pointerCoords,1, 1, downTime);getListener()->notifyMotion(&scrollArgs);}}

相关文章:

TV遥控器模拟鼠标键

需求 &#xff1a; tv上部分app不支持光标选中&#xff0c;如亚马逊&#xff0c;插上鼠标不方便&#xff0c;即可以用遥控器模拟鼠标滚动和点击 1.拦截上下左右键 在WMS::PhoneWindowManager::interceptKeyBeforeQueueing中监听上下左右左右键&#xff0c;进行拦截。 Overrid…...

检测判断IP合法性API接口

检测判断IP合法性API接口 一、检测判断IP合法性API接口二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、检测判断IP合法性API接口 一款免费的帮助你检测判断IP合法性API接口 二、…...

Linux swatch命令教程:如何监控系统活动(附案例详解和注意事项)

Linux swatch命令介绍 Swatch&#xff0c;全称为Simple Watcher&#xff0c;是一个简单的监视器&#xff0c;设计用于监控系统活动。为了使Swatch有用&#xff0c;它需要一个配置文件&#xff0c;该文件包含要查找的模式和在找到每个模式时要执行的操作。 Linux swatch命令适…...

加州大学伯克利分校研究人员推出Starling-7B:一款通过人工智能反馈强化学习(RLAIF)训练的开源大型语言模型(LLM)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

腾讯面试真题(C语言)

一.题目 求123...n&#xff0c;要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句&#xff08;A?B:C&#xff09;。 二.题目剖析 首先题目要求不能用乘除&#xff0c;那么&#xff08;首相末项&#xff09;*项数/2就不能用&#xff0c;其次不…...

JavaScript 函数

JavaScript 函数 函数就是封装起来可以被重复使用的代码块 函数的优点 使代码更加简洁方便代码的修改和维护使程序运行更加高效 函数的封装(创建 声明)和调用 封装 通过function关键字封装 function 函数名(参数) {函数体:被封装的代码 }匿名函数 将一个函数直接赋值给一…...

数据结构 | 查漏补缺之DFS、BFS、二次探测再散列法、完全二叉树、深度计算

目录 DFS&BFS 哈希表-二次探测再散列法 完全二叉树&深度计算 排序 快速排序-挖坑法 插入、选择、冒泡、区别 DFS&BFS 哈希表-二次探测再散列法 完全二叉树&深度计算 排序 快速排序-挖坑法 插入、选择、冒泡、区别 插入从第一个元素开始&#xff0c…...

用python实现单链表的基础操作

1 问题 用python实现单链表的基础操作&#xff1a;插入&#xff0c;删除&#xff0c;遍历&#xff0c;判空&#xff0c;清空链表&#xff0c;求长度&#xff0c;获取元素&#xff0c;判断元素是否存在。 2 方法 解决问题的步骤采用如下方式&#xff1a; 使用函数和类的方法来实…...

[头歌系统数据库实验] 实验3 MySQL的DDL语言

目录 第1关&#xff1a;将P表中的所有红色零件的重量增加6 第2关&#xff1a;把P表中全部红色零件的颜色改成蓝色 第3关&#xff1a;将SPJ表中由S5供给J4的零件P6改为由S3供应 第4关&#xff1a;将SPJ表中所有天津供应商的QTY属性值减少11&#xff08;用子查询方式&#x…...

系统运维安全之病毒自检及防护

一、前言 Linux勒索病毒&#xff08;Linux ransomware&#xff09;是一种最令人恶心的计算机恶意病毒&#xff0c;它以侵入Linux系统&#xff0c;捆绑文件并要求支付赎金才能释放文件为主要目的&#xff0c;破坏用户的数据&#xff0c;造成数据讹诈。Linux勒索病毒它们的存在已…...

Mabatis处理异常屏蔽SQL返回前端全局异常捕获处理

文章目录 Mabatis处理异常屏蔽SQL返回前端全局异常捕获处理结论1 java异常体系2 Spring框架异常处理3 定位Spring框架转化为哪种unchecked异常3.1 捕获RuntimeException定位Spring框架转化抛出的异常类3.2 进一步查看包名判断3.3 识别MyBatisSystemException下级实现3.3 识别My…...

黑豹程序员-java发邮件,发送内容支持html,带多附件的案例

介绍 发邮件mail是常见的软件功能&#xff0c;下面利于spring和java的mail库实现发送内容支持html&#xff0c;带多附件的案例 开启SMTP邮件发送协议 谁提供的SMTP邮件服务&#xff0c;就找谁开启。QQ邮箱类似。 依赖 <!--Java MAil 发送邮件API--><dependency&g…...

[LeetCode] 15. 三数之和

15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意&#xff1a;**答案中不可以包含重复…...

Android Chips(标签)

目录 一、流式布局标签发展历程 二、类型及使用 2.1 Chip.Action(默认值) 2.2 Chip.Entry 2.3 Chip.Filter 2.4 Chip.Choice 三、常用事件 3.1 OnClickListener 3.2 OnCheckedChangeListener 3.3 OnCloseIconClickListener 四、ChipGroup 4.1 ChipGroup Chip.Choi…...

飞行汽车开发原理(上)

前言 小节的安排是由浅入深&#xff0c;要按顺序读&#xff1b;有电路知识基础的同学可跳到“计算机电路”一节开始。因为知识点之间有网状依赖&#xff0c;没办法按分类来讲。 为了避免过于深入、越讲越懵&#xff0c;很多描述仅为方便理解、不求严谨。 半导体特性 导体&a…...

22、pytest多个参数化的组合

官方实例 # content of test_multi_parametrie.py import pytestpytest.mark.parametrize("x",[0,1]) pytest.mark.parametrize("y",[2,3]) def test_foo(x,y):print("{}-{}".format(x,y))pass解读与实操 要获得多个参数化参数的所有组合&…...

【网络奇缘】- 如何自己动手做一个五类|以太网|RJ45|网络电缆

​ ​ &#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 本篇文章关于计算机网络的动手小实验---如何自己动手做一个网线&#xff0c; 也是为后面的物理层学习进…...

【从零开始学习JVM | 第三篇】类的生命周期(高频面试)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。 在本文中&#xff0c;我们将深入探讨类的生命周期&#xff0c;从类加载到…...

详解前后端交互时PO,DTO,VO模型类的应用场景

前后端交互时的数据传输模型 前后端交互流程 前后端交互的流程: 前端与后端开发人员之间主要依据接口进行开发 前端通过Http协议请求后端服务提供的接口后端服务的控制层Controller接收前端的请求Contorller层调用Service层进行业务处理Service层调用Dao持久层对数据持久化 …...

力扣295. 数据流的中位数

优先队列 思路&#xff1a; 中位数是排序中间的数值&#xff1a;S1.M.S2可以使用两个优先队列来存放两边的数值&#xff0c;总是使得左侧的堆顶是最大的&#xff0c;右侧的堆顶是最小的&#xff0c;即使用大顶堆存放 S1&#xff0c;使用小顶堆存放S2&#xff0c;使得两个队列的…...

英语二笔记

完型填空 20题/0.5分 总分10, 至少拿8分 阅读理解A 20题/2分 总分40 至少拿24分 阅读理解B 5题/2分 总分10 至少拿6分 短文翻译 1题/15分 …...

【OpenSSH升级】升级后证书认证登录突然失效

上一篇“【OpenSSH升级】无论密码输入正确与否总是登录失败&#xff08;error: Could not get shadow information for root&#xff09;”总结了CentOS7上的openssh从7.4升级到9.4之后&#xff0c;密码认证失败问题&#xff0c;这里再总结一下证书认证失效问题。 大多数情况下…...

pytest +uiautomator2+weditor app自动化从零开始

目录结构1.0 把设备连接单独移出去了 模块操作代码&#xff0c;有一些流程操作和断言方法 from devices import dv from time import sleep import random from tool.jt import capture_screenshotdef initialization(func):def wrapper():sleep(1)dv.app_stop(com.visteon.…...

【计算机网络笔记】物理层——信道与信道容量

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…...

深度学习火车票识别系统 计算机竞赛

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 图像识别 火车票识别系统 该项目较为新颖&#xff0c;适…...

C++EasyX之井字棋

视频链接 井字棋 用EasyX和C实现井字棋小游戏 源码及注释 #include<graphics.h>char board_data[3][3] {{-,-,-},{-,-,-},{-,-,-}, };char current_piece O;//检测指定棋子的玩家是否获胜 bool CheckWin(char c) {// 检查每一行for (int i 0; i < 3; i){if (bo…...

12.5_黑马数据结构与算法Java

目录 001 二分查找 算法描述 002 二分查找 算法实现 003 二分查找 问题1 循环条件 004 二分查找 问题2 中间索引 thinking&#xff1a;反码补码原码&#xff1f; thinking&#xff1a;二进制转十进制&#xff1f; thinking&#xff1a;无符号右移&#xff1f; 005 二分…...

【PID学习笔记 5 】控制系统的性能指标之一

写在前面 PID在实际工程中最重要的工作就是调参&#xff0c;那么首先就要了解控制系统的性能指标。上文最后简要介绍了控制系统的基本要求&#xff0c;本文开始将系统学习控制系统的性能指标&#xff0c;内容比较多&#xff0c;初步计划是分三节来讲解。本文重点介绍性能指标的…...

HarmonyOS学习--TypeScript语言学习(三)

本章目录如下 一、条件语句 二、迭代器 三、循环 四、函数 五、类 一、条件语句 条件语句用于基于不同的条件来执行不同的动作。TypeScript 条件语句是通过一条或多条语句的执行结果&#xff08;True 或 False&#xff09;来决定执行的代码块。 在 TypeScript 中&#x…...

Matlab 镜像变换(2D)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 镜像变换是一个非常有趣的过程,它有着一个通用的套路(以2D为例):一个点围绕一个给定对称轴的镜像可以通过平移对称轴上一点,然后旋转它,使对称轴与x轴对齐,之后我们将旋转后的点的y坐标置为负,最后再将对称…...

城乡建设部网官方网站/市场推广方案ppt

我的环境 f.lux 我的使用感受是让屏幕看起来舒服一些&#xff0c;因为我有近视&#xff0c;所以需要保护眼睛。 f.lux官网&#xff1a;https://justgetflux.com/ f.lux v4.47 windows 10 x64 显示器&#xff1a;戴尔(DELL) P2414H 我最常用的色温值&#xff1a;5200 f.lux zipc…...

专门做澳大利亚项目的网站/上海百度seo网站优化

通过Java API来访问HDFS 1.Windows上配置环境变量 解压Hadoop&#xff0c;然后把Hadoop的根目录配置到HADOOP_HOME环境变量里面 然后把HADOOP_HOME/lib和HADOOP_HOME/bin配置到path里面 2.替换bin目录 将官网下载的Hadoop目录下面的bin目录替换成Windows下编译的Hadoop的bin目录…...

什么网站可以做会计题目/百度应用平台

不称深度指南&#xff0c;只愿浅度指北之前&#xff0c;用 VBA 开发了一个 Excel 插件「浅北表格助手」&#xff0c;随后&#xff0c;也发了两篇关于WordVBA 的教程&#xff0c;后台有小伙伴留言&#xff0c;说希望看到一些偏实用的代码。今天&#xff0c;它来了。我们在写 Wor…...

优速网站建设工作室/短网址在线生成

在上集中&#xff0c;我们已经构建了一个简单的待办列表应用&#xff08;to-do list app&#xff09;&#xff0c;这个应用可以在待办项过期时通过本地通知提醒用户。现在&#xff0c;我们要在之前的基础上添加以下功能&#xff1a;应用图标角标上显示过期待办项的数量、通知动…...

南岗区城市管理与建设网站/网络优化工程师前景如何

微擎安装 域名配到文件夹就行&#xff0c;安装数据库&#xff0c;设置登录密码 安装模块 将下载的模块直接放入 项目/addons中&#xff0c; 运行项目&#xff0c;体统管理底下就有未安装应用安装就行&#xff0c;绑定的小程序可随意填写&#xff1b; 执行以上操作后&#xf…...

网站负责人彩色验照/汕头seo公司

三、网络属性设置(如果你只有一台电脑&#xff0c;且外网IP就在服务器上&#xff0c;不做局域网主机的话&#xff0c;那么将不进行这个操作&#xff09;要使用以上所述服务&#xff0c;本机必须要有静态&#xff08;即固定&#xff09;的IP地址。如果只是在局域网中使用&#x…...