遥控器按键事件-PhoneWindowManager-配合实现文件管理器菜单功能

文章目录

一、概要-需求

Android 平台下一个文件管理器app,支持遥控器控制。那么在选中文件后如何实现菜单弹框,遥控器按键到菜单弹框是如何实现的?

这里面涉及到一些知识点,这里就是为了说明这些知识点,总结、归纳、整理。

如下,需求是鼠标点击菜单按键,如上被选中的文件就要出现菜单选项,能够实现如上功能。

二、参考资料-涉及到知识点

1、知识点

  • 蓝牙遥控器-按键值传递
  • Android 底层 按键值传递
  • Framework层: PhoneWindowManager 按键传递interceptKeyBeforeQueueing
  • 应用层:按键分发 dispatchKeyEvent

2、参考资料

源码相关

PhoneWindowManager 源码

遥控器相关

平板遥控器-屏蔽适配屏幕上下滑动-解决抖音上下滑动按键

MTK-Android12-适配蓝牙遥控器按键

三、整体架构流程

架构图如下,搞清楚流程非常重要,至少在需要改的层 要搞清楚在做什么,不然遇到问题一脸懵,不知道如何解决。

四、技术细节

创建策略层PhoneWindowManager 类中千万不要拦截-理解return 意义

可以查阅一下资料

PhoneWindowManager 源码

MTK-Android12-适配蓝牙遥控器按键

对比来看,看什么:源码中其实没有做任何拦截的,在部分按键时候定制它的功能。

再看:result 的变量值

如果返回0 ,不就是不分发了嘛。 所以,在定制功能的时候务必务必保证实际需求,是否需要传递到应用层,不然应用层接收不到按键事件。

所以 在日常开发过程中,可能不同项目需求 会更改返回值,务必去掉 或者 不要让返回值等于0 ,如下:

继续看看源码PhoneWindowManager方法interceptKeyBeforeQueueing 理解:它就是处理窗口策略的方法

应用层接收按键事件

基于如上 PhoneWindowManager 修改,那么应用层就能够收到按键事件了,如下:

java 复制代码
    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        //适配遥控器控制底部的recyclerView
        val keyCode = event.keyCode;
        Log.d(TAG,"============dispatchKeyEvent=========keyCode:$keyCode    event.action:${event.action}");
        if (keyCode == KeyEvent.KEYCODE_MENU && event.action == KeyEvent.ACTION_UP) {
            showFileMenuDialog();
            return true;
        }
        return super.dispatchKeyEvent(event)
    }

当应用层收到菜单按键事件的时候,直接显示菜单不就行了嘛。

总结

  • 遥控器物理按键是如何传递到应用层,每一层都要了解、理解,这样才能够对应不同的需求进行定制开发
  • 对于中间层 窗口管理,要了解PhoneWindowManager 做了什么,针对性的更改且理解interceptKeyBeforeQueueing 在做什么,这样才能够针对性的定制客需,实现客需。