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中的调用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 私有仓库部署和管理

目录 一、案例一 概述 二、案例一 前置知识点 2.1、什么是 Docker Compose 2.2、什么是 Consul 三、案例一 使用 docker Compose 搭建 Consul 集群环境 3.1、案例实验环境 3.2、案例需求 四、案例实施 4.1、Docker 网络通信 1&#xff09;端口映射 2&#xf…

运筹学_3.运输问题(特殊的线性规划)

目录 前言3.1 平衡运输问题中初始基可行解确定运输问题平衡运输与非平衡运输平衡运输问题的数学模型单纯形法解决平衡运输问题&#xff0c;初始可行基的确认 3.2 平衡运输问题的最优解判别求检验数表上作业法 3.3 产销不平衡的运输问题运输问题中产大于销的问题运输问题中产小于…

【MySQL访问】

文章目录 一、C远程连接到MySQLmysql_init()函数mysql_real_connect&#xff08;&#xff09;函数实战案例 二、处理查询select的细节mysql_store_result()函数获取结果行和列获取select结果获取行内容获取列属性 三、MySQL图形化界面连接 关于动态链接&#xff0c;请看这篇文章…

Nginx 实战-02-nginx proxy_pass 服务代理访问 使用笔记 ubuntu nodejs

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …

达梦数据库(五) -------- 达梦数据库+mybatisPlus+springboot

前言&#xff1a;安装完达梦数据库后&#xff0c;需要初始化实例&#xff0c;在初始化实例时&#xff0c;需要注意大小写敏感的设置。大小写敏感只能在初始化数据库的时候设置&#xff0c;默认为大小写敏感&#xff0c;一旦设置成功就无法修改&#xff0c;如果想要修改&#xf…

elementui el-tooltip文字提示组件弹出层内容格式换行处理

1、第一种 1.1 效果图 1.2、代码 <template><div class"wrapper"><el-tooltip class"content" effect"dark" placement"top"><div slot"content"><div v-html"getTextBrStr(text)"&…

centOS 编译C/C++

安装C和C编译器 yum -y install gcc*查看CenterOS系统信息 cat /etc/system-releaseCentOS Linux release 8.2.2004 (Core)查看gcc版本 gcc --versiongcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) Copyright (C) 2018 Free Software Foundation, Inc. This is free software…

深入理解同步与异步编程:从概念到实践

导言&#xff1a; 在软件开发中&#xff0c;同步和异步是两种常见的编程模式。深入理解这两种模式的工作原理对于提高代码的效率和性能至关重要。本文将从概念、原理和实践三个方面介绍同步和异步编程&#xff0c;帮助读者更好地理解和应用这两种编程模式。 同步编程&#xf…

ai虚拟主播自动切换的实现

前段时间,看到b站突然冒出很多ai主播,输入数字切换小姐姐.感觉挺有趣.思考了以下决定手动实现一下. 然后就陷入长达5天的踩坑中 由于是自建的webrtc服务器,很自然的想直接收流转发,这也是最优的方案, 然而实际上遇到许多不是很友好的bug, 然后再想使用rtp转发,依然不理想. 最后…

低代码开发:助企构建数字化应用平台

随着信息技术的快速发展&#xff0c;数字化应用平台已经成为企业提升竞争力、实现业务创新的关键。然而&#xff0c;传统的应用开发方式往往面临着开发周期长、成本高昂、技术门槛高等问题&#xff0c;这使得许多企业望而却步。而低代码开发技术的出现&#xff0c;为企业构建数…

【第十二节】C++控制台版本贪吃蛇小游戏

目录 一、游戏简介 1.1 游戏概述 1.2 实现功能 1.3 开发环境 二、实现设计 2.1 C类的设计 2.2 项目结构 2.3 代码设计 三、程序运行截图 3.1 游戏界面 3.2 自定义地图 3.3 常规游戏界面 一、游戏简介 1.1 游戏概述 本游戏是一款基于C语言开发的控制台版本贪吃蛇游…

cwiseMax、cwiseMin函数

一、cwiseMax含义 cwiseMax是Eigen库中的一个函数&#xff0c;用于求两个矩阵或向量的逐元素最大值。它的作用类似于std::max函数&#xff0c;但是可以同时处理多个元素&#xff0c;且支持矩阵和向量。 举例&#xff1a; 例如&#xff0c;对于两个向量a和b&#xff0c;cwiseMax…

Python中的魔法函数

大家好&#xff0c;Python作为一种高级编程语言&#xff0c;以其简洁、优雅和易读性而闻名。然而&#xff0c;Python的强大之处不仅仅在于其语法的简洁性&#xff0c;还在于其灵活的面向对象编程范式。在Python中&#xff0c;有一类特殊的方法被称为“魔法函数”&#xff0c;它…

神器!!Python热重载调试【送源码】

在 Python 开发的路上&#xff0c;调试是我们不可避免的一环。 而今天推荐的开源项目Reloadium &#xff0c;让你在不重启程序的情况下实现代码的即时更新和调试。 &#x1f504; Reloadium 功能亮点&#xff1a; 1. 热重载魔法&#xff1a; Reloadium 不仅仅能够实现代码的…

电脑缺失msvcp120.dll要如何解决,学会这七个方法,轻松摆脱困扰

msvcp120.dll 是 Microsoft Visual C 2013 运行时库的一部分&#xff0c;它提供了 C 标准库的实现&#xff0c;使得开发者能够利用丰富的 C 功能来构建复杂的应用程序。这个文件对于使用了 C 标准库的应用程序来说是必不可少的。当这些应用程序运行时&#xff0c;它们会动态链接…

Docker管理工具Portainer忘记admin登录密码

停止Portainer容器 docker stop portainer找到portainer容器挂载信息 docker inspect portainer找到目录挂载信息 重置密码 docker run --rm -v /var/lib/docker/volumes/portainer_data/_data:/data portainer/helper-reset-password生成新的admin密码&#xff0c;使用新密…

Ubuntu安装GCC编译器

GCC编译器安装 GCC编译器安装切换软件源(换成国内的服务器)1 、创建一个文本文档并命名为“sources.list”2 、复制软件源列表清华源:阿里源:3 、把修改之后的.list 文件覆盖原有的文件4 、更新软件列表5 、安装6 、检查是否安装成功7、GCC 编译器:GCC编译器安装 这里演示…

cdo | 常用命令

整理一下平时经常会使用的cdo命令 如何来更改netcdf数据中的变量名呢&#xff1f; 假设我现在有一个sst月平均数据,希望将里面的变量名称sst修改为sst_new netcdf oisst_monthly { dimensions:lat 180 ;lon 360 ;time UNLIMITED ; // (476 currently)nbnds 2 ; variable…

【PTA】7-4 朋友圈(C++ * 并查集思想)代码实现 一点反思

题目如下&#xff1a; AC代码如下&#xff08;参考PTA 7-2 朋友圈&#xff08;25 分&#xff09;_处理微信消息pta-CSDN博客&#xff09; #include<bits/stdc.h> using namespace std; #define sz 30005 typedef struct node{int rk, fa; }Node; Node tree[sz]; void In…

STL:copy简介

STL:copy STL算法&#xff1a;copy std::copy()函数使用 std::copy 函数在 中声明&#xff0c;属于变易算法(Modifying sequence operations)&#xff0c;主要用于实现序列数据的复制 template <class InputIterator, class OutputIterator>OutputIterator copy (InputI…