Qt 6.9 Android应用中如何通过USB-OTG访问USB设备?
我来帮你一步步解决这个问题,核心是要让Android系统识别到你的应用具备处理目标USB设备的能力,同时做好权限和代码层面的适配,具体操作如下:
1. 配置AndroidManifest.xml,让系统识别你的应用
这是让应用出现在“打开方式”列表的关键。你需要在项目的AndroidManifest.xml里添加USB相关的权限、功能声明,以及intent过滤器,告诉系统你的应用能处理USB设备连接事件。
首先添加USB Host权限和功能声明:
<uses-permission android:name="android.permission.USB_PERMISSION" /> <uses-feature android:name="android.hardware.usb.host" android:required="false" />
然后在主Activity标签内,添加处理USB设备连接的intent过滤器和元数据(注意和你现有Activity配置合并):
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:label="@string/app_name"> <!-- 保留你已有的其他配置 --> <intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" /> </activity>
2. 创建USB设备过滤规则文件
上面的配置引用了@xml/device_filter,你需要在项目的res/xml目录下创建这个device_filter.xml文件,用来定义你的应用要匹配的USB设备。可以指定特定厂商ID、产品ID,也可以匹配整个设备类别(比如存储设备、串口设备)。
比如匹配某个特定USB设备:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device vendor-id="1234" product-id="5678" /> </resources>
如果要匹配所有存储类设备(设备类代码为08),可以这样写:
<?xml version="1.0" encoding="utf-8"?> <resources> <usb-device class="08" /> </resources>
3. 主动申请USB权限(可选但推荐)
有时候系统不会自动弹出权限请求,这时候你需要在应用里主动向系统申请USB设备的访问权限。因为用的是Qt 6.9,得先启用Qt Android Extras模块,在.pro文件里添加:
QT += androidextras
然后在代码中添加权限检查逻辑(通过QAndroidJniObject调用Android原生API):
#include <QAndroidJniObject> #include <QAndroidIntent> #include <QDebug> void checkAndRequestUsbPermission() { // 获取Android系统的UsbManager QAndroidJniObject usbManager = QAndroidJniObject::callStaticObjectMethod( "android/content/Context", "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", QAndroidJniObject::getStaticObjectField("android/content/Context", "USB_SERVICE", "Ljava/lang/String;").object<jstring>() ); // 遍历所有连接的USB设备,这里以第一个设备为例 QAndroidJniObject deviceList = usbManager.callObjectMethod("getDeviceList", "()Ljava/util/HashMap;"); QAndroidJniObject entrySet = deviceList.callObjectMethod("entrySet", "()Ljava/util/Set;"); QAndroidJniObject iterator = entrySet.callObjectMethod("iterator", "()Ljava/util/Iterator;"); QAndroidJniObject targetDevice; if (iterator.callMethod<jboolean>("hasNext")) { QAndroidJniObject entry = iterator.callObjectMethod("next", "()Ljava/lang/Object;"); targetDevice = entry.callObjectMethod("getValue", "()Ljava/lang/Object;"); } if (targetDevice.isValid()) { // 检查是否已有设备访问权限 jboolean hasPermission = usbManager.callMethod<jboolean>("hasPermission", "(Landroid/hardware/usb/UsbDevice;)Z", targetDevice.object<jobject>()); if (!hasPermission) { // 发送权限请求广播 QAndroidJniObject permissionAction = QAndroidJniObject::getStaticObjectField( "android/hardware/usb/UsbManager", "ACTION_USB_PERMISSION", "Ljava/lang/String;"); QAndroidIntent permissionIntent(permissionAction.toString()); QAndroidJniObject appContext = QAndroidJniObject::callStaticObjectMethod( "org/qtproject/qt/android/QtNative", "context", "()Landroid/content/Context;"); QAndroidJniObject::callStaticMethod<void>( "android/content/Context", "sendBroadcast", "(Landroid/content/Intent;)V", permissionIntent.handle().object<jobject>() ); } } }
4. 确保项目资源被正确打包
把你的AndroidManifest.xml和res文件夹放在项目的android子目录下,然后在.pro文件中添加:
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
这样Qt编译Android安装包时,会自动包含这些自定义的Android配置文件。
按照这些步骤配置后,当你通过OTG线连接目标USB设备时,你的应用应该会出现在系统的“打开方式”列表里,也能正常访问USB设备的接口了。
内容来源于stack exchange




