Android TV WebView 遥控器按键处理:从全透传到白名单

Android TV WebView 遥控器按键处理:从全透传到白名单

问题

做 TV 看板 App 时,WebView 默认会把所有遥控器按键事件透传给网页。方向键、确定键给网页没问题,但音量键、电源键也进了网页 --- 这就很奇怪,网页要音量键干嘛?

常见的两种思路

黑名单

在 WebView 层拦截特定按键,不传进去:

kotlin 复制代码
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
    return when (event.keyCode) {
        KeyEvent.KEYCODE_VOLUME_UP,
        KeyEvent.KEYCODE_VOLUME_DOWN,
        KeyEvent.KEYCODE_POWER,
        ... // 来一个禁一个
        -> super.dispatchKeyEvent(event)
        else -> awContents.dispatchKeyEvent(event)
    }
}

问题很明显:遥控器按键几十个,漏一个就是一个坑。

白名单(推荐)

反过来,只放行网页真正需要的按键,其余全部走系统默认:

kotlin 复制代码
// 白名单:只把这些导航键传给 WebView
private val webViewKeys = setOf(
    KeyEvent.KEYCODE_DPAD_UP,      // 方向键上
    KeyEvent.KEYCODE_DPAD_DOWN,    // 方向键下
    KeyEvent.KEYCODE_DPAD_LEFT,    // 方向键左
    KeyEvent.KEYCODE_DPAD_RIGHT,   // 方向键右
    KeyEvent.KEYCODE_DPAD_CENTER,  // 确定键
    KeyEvent.KEYCODE_ENTER,        // 回车(外接键盘)
    KeyEvent.KEYCODE_BACK          // 返回
)

关键是在 Activity 层拦截,而不是 WebView 层:

kotlin 复制代码
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
    // 白名单内的键正常分发(进入 WebView)
    if (event.keyCode in webViewKeys) {
        return super.dispatchKeyEvent(event)
    }
    // 菜单键:弹出 URL 选择列表
    if (event.keyCode == KeyEvent.KEYCODE_MENU && event.action == KeyEvent.ACTION_DOWN) {
        showUrlSelectionDialog()
        return true
    }
    // 其余按键(音量、电源、主页、数字键...)交给系统
    return super.dispatchKeyEvent(event)
}

为什么是这几个键

按键 原因
DPAD_UP/DOWN/LEFT/RIGHT 看板页面有可滚动内容、可聚焦元素,依赖遥控器方向键导航
DPAD_CENTER 遥控器中间的确定键,是点击网页按钮/链接的唯一方式
ENTER 外接键盘发送的确认键,行为和 DPAD_CENTER 等价
BACK onBackPressed 里用它判断 WebView 历史,先网页回退再退 App
MENU App 级功能,单独拦截,弹出地址选择列表

不在白名单里的(音量、静音、电源、主页、数字键、媒体键...)一律不进 WebView,系统该怎么响应就怎么响应。

总结

  • 黑名单累了维护人,白名单溜了漏网鱼
  • WebView 只配拿到它需要的键
  • 拦截放在 Activity 层,别在 WebView 里搞
相关推荐
事圆则缓33 分钟前
Java 8 Lambda、Stream、Optional 与 Android 边界:从回调语法到运行时兼容
android·java
mmsx1 小时前
Android 地图十万要素不卡顿:空间网格 + 渐进式加载的移动端实践
android·大数据·opengl
Godikov2 小时前
Android 工业终端保活实战:前台服务 + 开机自启 + 更新自启的三重保障
android
字节暗面2 小时前
SO加固强度怎么量化?腾讯ACE与FairGuard静态分析实测
android·逆向
终端安全笔记4 小时前
描述文件、企业证书、MDM 不是三个名字,是三层
android·ios·智能手机
字节暗面4 小时前
一次游戏安全SO静态分析记录:腾讯ACE与FairGuard加固强度对比
android·逆向工程·游戏加固
传奇开心果编程5 小时前
【Jetpack Compose基础语法学与练】第9课 SideEffect副作用 + LaunchedEffect,处理异步任务和生命周期
android·学习·ui·kotlin·android jetpack
2401_833269307 小时前
RecyclerView多布局详解
android
v_34836087627 小时前
Android_8 zygote启动分析
android
消失的旧时光-19437 小时前
Android 系统层扫盲 11:JNI 到底是什么?Java / Kotlin 是怎么调用 C/C++ 的?
android·binder·zygote·system_server·aops