Android NDK Native Activity无法捕获鼠标按键释放事件问题排查
Android NDK Native Activity鼠标释放事件检测问题修复
原代码的核心问题
错误的事件Action获取方式:
处理AINPUT_EVENT_TYPE_MOTION类型事件时,你误用了AKeyEvent_getAction(event)——这个函数仅适用于键盘事件(AINPUT_EVENT_TYPE_KEY)。Motion事件必须使用AMotionEvent_getAction(event)获取action,否则会拿到错误值,导致AMOTION_EVENT_ACTION_UP分支根本不会触发。释放事件的按键判断逻辑错误:
鼠标释放事件触发时,AMotionEvent_getButtonState(event)返回的是当前仍处于按下状态的按键,而非刚刚释放的按键。原代码中用mouseButton & AMOTION_EVENT_BUTTON_PRIMARY判断释放事件永远不会成立,因为此时对应按键已松开,button state中不再包含该标记。
正确的实现代码
// LOGI是__android_log_print的宏定义 int32_t eventType = AInputEvent_getType(event); switch(eventType) { case AINPUT_EVENT_TYPE_MOTION: { int32_t eventAction = AMotionEvent_getAction(event); // 改用Motion事件专属的Action获取函数 int32_t eventPointerIndex = (eventAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; int32_t actionMasked = eventAction & AMOTION_EVENT_ACTION_MASK; int32_t actionButton = AMotionEvent_getActionButton(event); // 获取触发当前事件的具体按键 switch(actionMasked) { case AMOTION_EVENT_ACTION_DOWN: { int32_t toolType = AMotionEvent_getToolType(event, eventPointerIndex); if (toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) { int32_t mouseButton = AMotionEvent_getButtonState(event); if (mouseButton & AMOTION_EVENT_BUTTON_PRIMARY) LOGI("Left Click Press"); else if(mouseButton & AMOTION_EVENT_BUTTON_SECONDARY) LOGI("Right Click Press"); else if(mouseButton & AMOTION_EVENT_BUTTON_TERTIARY) LOGI("3rd Click Press"); } break; } case AMOTION_EVENT_ACTION_UP: { int32_t toolType = AMotionEvent_getToolType(event, eventPointerIndex); if (toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) { // 通过actionButton判断被释放的具体按键 if (actionButton == AMOTION_EVENT_BUTTON_PRIMARY) LOGI("Left Click Release"); else if(actionButton == AMOTION_EVENT_BUTTON_SECONDARY) LOGI("Right Click Release"); else if(actionButton == AMOTION_EVENT_BUTTON_TERTIARY) LOGI("3rd Click Release"); } break; } } break; } }
关键修复点说明
- 替换Action获取函数:将
AKeyEvent_getAction改为AMotionEvent_getAction,确保正确识别Motion事件的action类型。 - 改用ActionButton判断释放动作:
AMotionEvent_getActionButton会直接返回触发当前UP事件的按键,这是检测鼠标释放动作的标准方式。 - 简化冗余分支:去掉不必要的嵌套switch,让代码逻辑更清晰。
内容的提问来源于stack exchange,提问作者Techie-Guy
相关产品推荐
相关产品推荐

