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

相关文章

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib