You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NDK+Rust无法捕获USB游戏手柄/摇杆输入事件求助

USB游戏手柄事件捕获问题排查方案

先排查winit的基础配置

  • 升级winit到最新稳定版:旧版本对Android游戏手柄事件的支持存在兼容性问题,新版本通常会修复这类设备适配问题。
  • 确认窗口初始化时正确关联Android上下文:winit在Android上需要依赖ndk_context获取上下文,否则可能无法接收全量输入事件:
    use ndk_context::android_context;
    use winit::platform::android::EventLoopBuilderExtAndroid;
    
    let event_loop = winit::event_loop::EventLoopBuilder::new()
        .with_android_context(android_context().unwrap())
        .build();
    

补全Android权限配置

在AndroidManifest.xml中添加必要的权限和特性声明:

<!-- 声明支持游戏硬件 -->
<uses-feature android:name="android.hardware.gamepad" android:required="false" />
<!-- USB设备访问权限 -->
<uses-permission android:name="android.permission.USB_PERMISSION" />

同时需要动态申请USB权限,避免系统拦截设备访问:

use ndk::permission::Permission;
use ndk_context::android_context;

if let Some(ctx) = android_context() {
    if let Some(activity) = ctx.activity() {
        ndk::permission::request_permissions(activity, vec![Permission::USB_PERMISSION], |results| {
            for (perm, granted) in results {
                if perm == Permission::USB_PERMISSION && !granted {
                    // 权限申请失败,提示用户开启
                }
            }
        });
    }
}

绕过winit直接用NDK监听事件

如果winit的输入处理存在局限性,直接通过NDK的InputManager监听游戏手柄事件:

use ndk::event::InputEvent;
use ndk::input::{Axis, InputDeviceType, InputManager};

let input_manager = InputManager::new().expect("Failed to create InputManager");
// 筛选出所有游戏手柄设备
let gamepad_devices = input_manager.get_devices(Some(InputDeviceType::Gamepad));

for device in gamepad_devices {
    let _ = input_manager.register_listener(device.id(), |event| {
        match event {
            InputEvent::Motion(motion) => {
                // 读取摇杆、扳机轴数据
                let left_x = motion.get_axis_value(Axis::LEFT_X);
                let right_trigger = motion.get_axis_value(Axis::RIGHT_TRIGGER);
                // 这里添加你的事件处理逻辑
            }
            InputEvent::Key(key) => {
                // 处理按键事件(如A/B/X/Y键)
                let key_code = key.key_code();
                // 这里添加你的按键处理逻辑
            }
            _ => {}
        }
        true // 返回true表示事件已处理
    });
}

验证事件映射匹配度

打印所有输入事件的详细参数(比如轴类型、键码),对比「Game Controller Tester」的输出,确认是否有事件被winit过滤。部分Xbox手柄的特殊按键可能被映射为非标准轴/键码,需要针对性处理。

内容的提问来源于stack exchange,提问作者Ha421

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:07:15