Qt for android : libusb在android中使用

2024-05-29 01:36
文章标签 android 使用 qt libusb

本文主要是介绍Qt for android : libusb在android中使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

如何在Qt for Android中使用libusb, 其实libusb的文档里面都写的很清楚, 这里只是稍微做下整理。

libusb

libusb github源码
libusb release的版本, 有编译好的静态

步骤

1. 下载libusb

libusb v1.0.027 源码包

2. 整理提取libusb android使用源码

从编译文件 libusb-1.0.27\android\jni\libusb.mk 直到 android所需要的源文件和头文件, 做整理,编译时再看缺少哪些,补齐。
如下是我整理的, config.h 来自libusb-1.0.27\android目录
在这里插入图片描述
下面是libusb目录包含的文件
在这里插入图片描述
os目录包含的文件
在这里插入图片描述

libusb.pri

CCFLAG += -fvisibility=hidden -pthreadINCLUDEPATH += $$PWDSOURCES += \$$PWD/libusb/core.c \$$PWD/libusb/descriptor.c \$$PWD/libusb/hotplug.c \$$PWD/libusb/io.c \$$PWD/libusb/strerror.c \$$PWD/libusb/sync.c \$$PWD/os/events_posix.c \$$PWD/os/linux_netlink.c \$$PWD/os/linux_usbfs.c \$$PWD/os/threads_posix.cHEADERS += \$$PWD/config.h \$$PWD/libusb/libusb.h \$$PWD/libusb/libusbi.h \$$PWD/libusb/version.h \$$PWD/libusb/version_nano.h \$$PWD/os/events_posix.h \$$PWD/os/linux_usbfs.h \$$PWD/os/threads_posix.h

3. 创建Qt for Android 并 加入libusb

参考 Qt for android 获取USB设备列表(二)JNI方式 获取,

  1. 工程文件.pro 添加libusb支持
    include ($$PWD/libusb/libusb.pri)
  2. java代码支持, 用于获取usb权限
package usb;import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.io.IOException;import android.content.pm.PackageManager;
import android.Manifest;
import android.content.Intent;
import android.app.PendingIntent;
import android.util.Log;
import android.os.Bundle;
import android.content.Context;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;// import com.hoho.android.usbserial.driver.Ch34xSerialDriver;
// import com.hoho.android.usbserial.driver.UsbSerialPort;public class USBListActivity extends org.qtproject.qt.android.bindings.QtActivity
{private static USBListActivity instance = null;private static UsbManager usbManager = null;// private static StorageManager storageManager = null;private static String tag = "MainClass";private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";public USBListActivity(){instance = this;}@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);usbManager = (UsbManager)getSystemService(Context.USB_SERVICE);// storageManager = (UsbManager)getSystemService(Context.STORAGE_SERVICE);Log.i(tag, "checkPermission: " + checkPermission());// getDeviceList();}private boolean checkPermission() {int readPermission = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);int writePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);return readPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;}public static boolean requestUSBPermission(String portName){if (portName.isEmpty()){Log.i(tag, "port empty");return false;}HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();UsbDevice device = null;for (Map.Entry<String, UsbDevice> entry : deviceList.entrySet()){if (portName.equals(entry.getKey())){device = entry.getValue();break;}}if (device == null){Log.i(tag, "device not exists");return false;}if (!usbManager.hasPermission(device)){Intent permissionIntent = new Intent(ACTION_USB_PERMISSION);PendingIntent pendingIntent = PendingIntent.getBroadcast(instance,0,permissionIntent,PendingIntent.FLAG_UPDATE_CURRENT);usbManager.requestPermission(device, pendingIntent);if (!usbManager.hasPermission(device)){Log.i(tag, "permission denied");return false;}}// UsbDeviceConnection deviceConnection = usbManager.openDevice(device);// if (null == deviceConnection)// {//     Log.i(tag, "fail to open device");//     return false;// }return true;}public void getDeviceList(){HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();System.out.println("------------------------->GetDeviceList<-------------------------");deviceList.forEach((key, value) -> {System.out.println("------------------------->" + key + "<-------------------------");System.out.println(value);System.out.println("<-------------------------" + key + "------------------------->");});System.out.println("<-------------------------GetDeviceList------------------------->");}
}
  1. 将libusb示例加入到Qt for android工程
    将 libusb-1.0.27\android\examples 目录下的 unrooted_android.c和unrooted_android.h拷贝到Qt 项目中, 添加

  2. Qt for Android通过JNI调用获取文件描述符并使用libusb打印usb设备信息

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "unrooted_android.h"
#include <QJniObject>
#include <QJniEnvironment>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);connect(ui->btnRefreshPortNames, &QPushButton::clicked,this, [=](){ui->cbPortNames->clear();ui->cbPortNames->addItems(getSerialPorts());});connect(ui->btnTest, &QPushButton::clicked,this, &MainWindow::test);emit ui->btnRefreshPortNames->clicked(); // 借势初始化
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::logger(const QString &text)
{ui->textEdit->append(text);
}QList<QString> MainWindow::getSerialPorts()
{QList<QString> names;
#ifdef Q_OS_ANDROIDQJniObject usbService = QJniObject::getStaticObjectField("android/content/Context","USB_SERVICE","Ljava/lang/String;");if (!usbService.isValid()){logger("fail to get usb service");return names;}QJniObject activity = QJniObject(QNativeInterface::QAndroidApplication::context());QJniObject usbManager = activity.callObjectMethod("getSystemService","(Ljava/lang/String;)Ljava/lang/Object;",usbService.object<jstring>());if (!usbManager.isValid()){logger("fail to get usb manager");return names;}QJniObject usbDeviceListHashMap = usbManager.callObjectMethod("getDeviceList","()Ljava/util/HashMap;");QJniObject devListKeySet = usbDeviceListHashMap.callObjectMethod("keySet","()Ljava/util/Set;");QJniObject devListIter = devListKeySet.callObjectMethod("iterator","()Ljava/util/Iterator;");jint devListSize = usbDeviceListHashMap.callMethod<jint>("size", "()I");QJniObject usbDevObj;QJniObject usbDevObjIter;int vid = 0, pid = 0;QString devName;for (int i = 0; i < devListSize; ++i){usbDevObjIter = devListIter.callObjectMethod("next","()Ljava/lang/Object;");usbDevObj = usbDeviceListHashMap.callObjectMethod("get","(Ljava/lang/Object;)Ljava/lang/Object;",usbDevObjIter.object());vid = usbDevObj.callMethod<jint>("getVendorId", "()I");pid = usbDevObj.callMethod<jint>("getProductId", "()I");devName = usbDevObj.callMethod<jstring>("getDeviceName", "()Ljava/lang/String;").toString();logger(QString("Name: %1, VID: %2, PID: %3").arg(devName).arg(vid).arg(pid));names.append(devName);}
#elsefor (QSerialPortInfo &info : QSerialPortInfo::availablePorts()){names.append(info.portName());}
#endifreturn names;
}void MainWindow::test()
{QJniObject str = QJniObject::fromString(ui->cbPortNames->currentText());jboolean res = QJniObject::callStaticMethod<jboolean>("usb/USBListActivity","requestUSBPermission","(Ljava/lang/String;)Z",str.object<jstring>());if (!res){logger("permission denied");return;}QJniObject usbService = QJniObject::getStaticObjectField("android/content/Context","USB_SERVICE","Ljava/lang/String;");if (!usbService.isValid()){logger("fail to get usb service");return;}QJniObject activity = QJniObject(QNativeInterface::QAndroidApplication::context());QJniObject usbManager = activity.callObjectMethod("getSystemService","(Ljava/lang/String;)Ljava/lang/Object;",usbService.object<jstring>());if (!usbManager.isValid()){logger("fail to get usb manager");return;}QJniObject usbDeviceListHashMap = usbManager.callObjectMethod("getDeviceList","()Ljava/util/HashMap;");QJniObject devListKeySet = usbDeviceListHashMap.callObjectMethod("keySet","()Ljava/util/Set;");QJniObject devListIter = devListKeySet.callObjectMethod("iterator","()Ljava/util/Iterator;");jint devListSize = usbDeviceListHashMap.callMethod<jint>("size", "()I");QJniObject usbDevObj;QJniObject usbDevObjIter;QString devName;QJniObject selectedUsbDevice;for (int i = 0; i < devListSize; ++i){usbDevObjIter = devListIter.callObjectMethod("next","()Ljava/lang/Object;");usbDevObj = usbDeviceListHashMap.callObjectMethod("get","(Ljava/lang/Object;)Ljava/lang/Object;",usbDevObjIter.object());devName = usbDevObj.callMethod<jstring>("getDeviceName", "()Ljava/lang/String;").toString();if (devName != ui->cbPortNames->currentText()){continue;}selectedUsbDevice = usbDevObj;break;}if (!selectedUsbDevice.isValid()){logger("device not found");return;}QJniObject usbConnection = usbManager.callObjectMethod("openDevice","(Landroid/hardware/usb/UsbDevice;)Landroid/hardware/usb/UsbDeviceConnection;",selectedUsbDevice.object());if (!usbConnection.isValid()){logger("fail to get usb connection");return;}jint fd = usbConnection.callMethod<jint>("getFileDescriptor", "()I");unrooted_usb_description(fd);logger("libusb test finished7");
}

4. 手机接入OTG和USB设备

我这里接的是USB转TTL线

5. 测试

打印信息是

D LibUsb : Dev (bus 1, device 4): 1A86 - 7523 speed: 12M
D LibUsb : Product: USB2.0-Serial
D LibUsb : Configuration:
D LibUsb : wTotalLength: 39
D LibUsb : bNumInterfaces: 1
D LibUsb : bConfigurationValue: 1
D LibUsb : iConfiguration: 0
D LibUsb : bmAttributes: 80h
D LibUsb : MaxPower: 48
D LibUsb : Interface:
D LibUsb : bInterfaceNumber: 0
D LibUsb : bAlternateSetting: 0
D LibUsb : bNumEndpoints: 3
D LibUsb : bInterfaceClass: 255
D LibUsb : bInterfaceSubClass: 1
D LibUsb : bInterfaceProtocol: 2
D LibUsb : iInterface: 0
D LibUsb : Endpoint:
D LibUsb : bEndpointAddress: 82h
D LibUsb : bmAttributes: 02h
D LibUsb : wMaxPacketSize: 32
D LibUsb : bInterval: 0
D LibUsb : bRefresh: 0
D LibUsb : bSynchAddress: 0
D LibUsb : Endpoint:
D LibUsb : bEndpointAddress: 02h
D LibUsb : bmAttributes: 02h
D LibUsb : wMaxPacketSize: 32
D LibUsb : bInterval: 0
D LibUsb : bRefresh: 0
D LibUsb : bSynchAddress: 0
D LibUsb : Endpoint:
D LibUsb : bEndpointAddress: 81h
D LibUsb : bmAttributes: 03h
D LibUsb : wMaxPacketSize: 8
D LibUsb : bInterval: 1
D LibUsb : bRefresh: 0
D LibUsb : bSynchAddress: 0

在这里插入图片描述

代码

基本代码都提供了, 没必要下载
libusb在Qt for android中的调用

这篇关于Qt for android : libusb在android中使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1012270

相关文章

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是

嵌入式数据库SQLite 3配置使用讲解

《嵌入式数据库SQLite3配置使用讲解》本文强调嵌入式项目中SQLite3数据库的重要性,因其零配置、轻量级、跨平台及事务处理特性,可保障数据溯源与责任明确,详细讲解安装配置、基础语法及SQLit... 目录0、惨痛教训1、SQLite3环境配置(1)、下载安装SQLite库(2)、解压下载的文件(3)、

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

Springboot如何正确使用AOP问题

《Springboot如何正确使用AOP问题》:本文主要介绍Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录​一、AOP概念二、切点表达式​execution表达式案例三、AOP通知四、springboot中使用AOP导出

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

python 常见数学公式函数使用详解(最新推荐)

《python常见数学公式函数使用详解(最新推荐)》文章介绍了Python的数学计算工具,涵盖内置函数、math/cmath标准库及numpy/scipy/sympy第三方库,支持从基础算术到复杂数... 目录python 数学公式与函数大全1. 基本数学运算1.1 算术运算1.2 分数与小数2. 数学函数