讨论广场 问答详情
[求助]OpenHarmony新增按键
针尖拔麦芒 2025-12-10 13:44:48
143 评论 分享

设备rk3566,系统oh5.0.0,从底层适配了相关外设驱动,这些外设主要是通过按键方式使用.现在按下这些按键,hilog能够捕获到一些信息,但是我也不太懂.然后我在上层写了一个简单的应用程序,代码如下所受

import { KeyCode } from '@kit.InputKit';

@Entry
@Component
struct Index {
  @State message: string = 'key value test';
  @State keyInfo: string = '等待按键输入...';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Top },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .margin({ top: 100 })

      Text(this.keyInfo)
        .id('KeyInfo')
        .fontSize(20)
        .fontColor(Color.Blue)
        .textAlign(TextAlign.Center)
        .width('80%')
        .margin({ top: 200 })
        .alignRules({
          center: { anchor: 'HelloWorld', align: VerticalAlign.Bottom },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })

      Button('测试按键')
        .id('TestButton')
        .fontSize(18)
        .margin({ top: 300 })
        .onClick(() => {
          this.message = '请按下任意键测试...';
        })
        .alignRules({
          center: { anchor: 'KeyInfo', align: VerticalAlign.Bottom },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
    .onKeyEvent((event: KeyEvent) => {
      const keyCode: number = event.keyCode;
      const action: number = event.type;

      let keyName: string = this.getKeyName(keyCode);
      this.keyInfo = `KeyCode: ${keyCode}, 按键: ${keyName}, 动作: ${action === 0 ? '按下' : '释放'}`;
      console.log(`按键捕获 - KeyCode: ${keyCode}, 按键: ${keyName}, 动作: ${action}`);
    })
  }

  // 更新按键映射,包含你实际遇到的按键
  getKeyName(keyCode: number): string {
    switch (keyCode) {
      // 你实际遇到的按键
      case KeyCode.KEYCODE_SOUND:      // 2833
        return '音量键';
      case KeyCode.KEYCODE_ASSISTANT:  // 2722
        return '助手键';

      // 基础导航键
      case KeyCode.KEYCODE_HOME:
        return '主页';
      case KeyCode.KEYCODE_BACK:
        return '返回';
      case KeyCode.KEYCODE_MENU:
        return '菜单';

      // 方向键
      case KeyCode.KEYCODE_DPAD_UP:
        return '上';
      case KeyCode.KEYCODE_DPAD_DOWN:
        return '下';
      case KeyCode.KEYCODE_DPAD_LEFT:
        return '左';
      case KeyCode.KEYCODE_DPAD_RIGHT:
        return '右';
      case KeyCode.KEYCODE_DPAD_CENTER:
        return '中键/确认';

      // 标准音量键
      case KeyCode.KEYCODE_VOLUME_UP:
        return '音量+';
      case KeyCode.KEYCODE_VOLUME_DOWN:
        return '音量-';
      case KeyCode.KEYCODE_VOLUME_MUTE:
        return '静音';

      // 电源和相机
      case KeyCode.KEYCODE_POWER:
        return '电源';
      case KeyCode.KEYCODE_CAMERA:
        return '拍照';

      // 媒体键
      case KeyCode.KEYCODE_MEDIA_PLAY_PAUSE:
        return '播放/暂停';
      case KeyCode.KEYCODE_MEDIA_NEXT:
        return '下一首';
      case KeyCode.KEYCODE_MEDIA_PREVIOUS:
        return '上一首';

      // 功能键
      case KeyCode.KEYCODE_ESCAPE:
        return 'Esc';
      case KeyCode.KEYCODE_F1:
        return 'F1';
      case KeyCode.KEYCODE_F2:
        return 'F2';
      case KeyCode.KEYCODE_F3:
        return 'F3';
      case KeyCode.KEYCODE_F4:
        return 'F4';
      case KeyCode.KEYCODE_F5:
        return 'F5';
      case KeyCode.KEYCODE_F10:
        return 'F10';

      default:
        return `未知按键(${keyCode})`;
    }
  }
}

我点击连接到设备上的外设,是可以看到有相应的键值上报,后续如果要接着处理,那就可以根据这个键值去开发相应的功能.但是我发现这个键值好像是系统自带的.我按下按键,会有如下输出

12-10 13:33:16.215 13680 13680 I A03d00/JSAPP: 按键捕获 - KeyCode: 2833, 按键: 音量键, 动作: 0
12-10 13:33:16.360   346  1252 I C02802/KeyAutoRepeat: [K:U:190][SelectAutoRepeat:125] Stop autorepeat, keyCode:<private>, repeatKeyCode:<private>, keyAction: <private>, timeId:<private>
12-10 13:33:16.362 13680 13680 I A03d00/JSAPP: 按键捕获 - KeyCode: 2833, 按键: 音量键, 动作: 1
12-10 13:33:25.919 13680 13680 I A03d00/JSAPP: 按键捕获 - KeyCode: 2833, 按键: 音量键, 动作: 0
12-10 13:33:26.080   346  1252 I C02802/KeyAutoRepeat: [K:U:192][SelectAutoRepeat:125] Stop autorepeat, keyCode:<private>, repeatKeyCode:<private>, keyAction: <private>, timeId:<private>
12-10 13:33:26.082 13680 13680 I A03d00/JSAPP: 按键捕获 - KeyCode: 2833, 按键: 音量键, 动作: 1

说明系统上报了对应的事件,而且应用也能够捕获到按下按键.但是我始终觉得怪怪的.在foundation/multimodalinput/input/service/event_handler/src/key_event_value_transformation.cpp中能够看到有我使用的键值2833和2722的定义和转换

{249, {"KEY_SOUND", 249, 2833, HOS_KEY_SOUND}},
 {251, {"KEY_ASSISTANT", 251, 2722, HOS_KEY_ASSISTANT}},

而且这个在应用代码中通过跳转到@ohos.multimodalInput.keyCode.d.ts中也能看到KEY_SOUND和KEY_ASSISTANT的值.这里面有的值,我肯定可以通过keyCode去调用,可是如果是我自己新增的按键值,这里面没有相关的定义,应用怎么能够识别到呢.

另外在Linux中的按键定义好像又不一样,我在out/kernel.src_tmp/linux-5.10/include/uapi/linux/input-event-codes.h和kernel/linux/linux-5.10/include/uapi/linux/input-event-codes.h中关于KEY_SOUND和KEY_ASSISTANT中的定义值又不一致

#define KEY_SOUND		213
#define KEY_ASSISTANT		0x247	/* AL Context-aware desktop assistant */

而且感觉描述上好像有不一致了.这种是怎么回事啊,感觉我好混乱好懵逼,不知道哪里是哪里.而且要新增按键,还能再应用中捕获到应该怎么做啊,还请各位大佬指点指点.

143 评论 分享
写回答
全部评论(6)
1 楼

键值表:

https://gitcode.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-input-kit/js-apis-keycode.md

使用injectEvent 注入事件来发送key值,需要添加权限。

inputEventClient.injectEvent({ KeyEvent: this.xxxKeyDown });
private xxxKeyDown : inputEventClient.KeyEvent = {
  isPressed: true,
  keyCode: 2722,
  keyDownDuration: 100,
  isIntercepted: false
}

 

2025-12-10 13:55:43
2025-12-10 16:35:32
引用:“是的 理解到位!”
太感谢您啦,非常感谢您的帮助!
2025-12-10 16:35:32
2025-12-10 15:56:52
引用:“那是不是可以这样理解,如果是系统内已经注册的,应用中可以直接使用。而如果是自己新增的按键和按键值,则需要在应用中添加这个权限,并且添加这个权限后,应用调用新注册的键值也是由系统来完成这个注入过程,而不是我们来进行显示的注入。”
是的 理解到位!
2025-12-10 15:56:52
2025-12-10 15:41:20
引用:“是的 这些键值 事件注入 框架都是有绑定对应的 功能点的,不需要再额外注入。 如果新增的按键及键值,则需要自己重新绑定事件或能力。 目前事件注入是 系统能力,需要额外增加ohos.permission.INJECT_INPUT_EVENT权限。 ”
那是不是可以这样理解,如果是系统内已经注册的,应用中可以直接使用。而如果是自己新增的按键和按键值,则需要在应用中添加这个权限,并且添加这个权限后,应用调用新注册的键值也是由系统来完成这个注入过程,而不是我们来进行显示的注入。
2025-12-10 15:41:20
2025-12-10 15:17:58
引用:“我再应用中也没有通过injectEvent注入事件,2833和2722这两个键值应该是系统就已经注入了对应的事件吧,然后只是在key_event_value_transformation.cpp文件中有对应的映射。这是不是意味着添加的外设键值要做一次重新映射,和新的注入才可以实现新增的外设键值,但是有个问题:@ohos.multimodalInput.keyCode.d.ts是full-sdk中的”
是的 这些键值 事件注入 框架都是有绑定对应的 功能点的,不需要再额外注入。 如果新增的按键及键值,则需要自己重新绑定事件或能力。 目前事件注入是 系统能力,需要额外增加ohos.permission.INJECT_INPUT_EVENT权限。
2025-12-10 15:17:58
2025-12-10 15:04:08
我再应用中也没有通过injectEvent注入事件,2833和2722这两个键值应该是系统就已经注入了对应的事件吧,然后只是在key_event_value_transformation.cpp文件中有对应的映射。这是不是意味着添加的外设键值要做一次重新映射,和新的注入才可以实现新增的外设键值,但是有个问题:@ohos.multimodalInput.keyCode.d.ts是full-sdk中的内容,如果新加的键值这里没有标识的话,那我在应用中不是不能直接通过keyCode进行使用了
2025-12-10 15:04:08