当前位置: 首页 > news >正文

Qt for android 串口库使用

简介

由于Qt for android并没有提供android的串口执行方案,基于需要又懒得自己去造轮子, 使用开源的
usb-serial-for-android 库进行串口访问读写。
如果有自己的需要和库不满足的点,可以查看库的底层调用的Android相关API + C/C++ 串口库 + 对应串口设备的开源驱动代码进行改造。

Note: 由于我没有系统的学习过Java、Android, 如果涉及到认知冲突, 请信自己[礼貌不失尴尬的微笑]。

步骤

1. 下载 usb-serial-for-android release版本

usb-serial-for-android_v3.7.2.zip

2. 解压缩

解压缩之后目录呈现如下图, 移植的代码在usbSerialForAndroid目录下

在这里插入图片描述

3. 加入Qt for Android项目

将usbSerialForAndroid/src/main/java/com目录整个拷入到Qt for
android生成的Android目录下

在这里插入图片描述

Qt for android 工程目录下的android源码目录

在这里插入图片描述

4. 设置Qt Creator显化java代码

DISTFILES +=
android/src/com/hoho/android/usbserial/driver/.java \
android/src/com/hoho/android/usbserial/util/
.java
在这里插入图片描述

5. 编译和解决报错

在这里插入图片描述

错误1 BuildConfig不存在

BuildConfig 是 gradle自动生成的,移植的时候并没有一起移植过来, 所以有几种方案:

1) 注释掉掉BuildConfig相关信息代码
2) Qt for android本身的项目也生成BuildConfig, 将 引用包由原先

import com.hoho.android.usbserial.BuildConfig; 改成
import org.qtproject.example.BuildConfig;

3) 创建BuildConfig.java,导入或者自定义相关使用字段(我目前使用的)
package com.hoho.android.usbserial;
public final class BuildConfig {public static final boolean DEBUG = false;public static final String APPLICATION_ID = "org.qtproject.example";public static final String BUILD_TYPE = "release";public static final int VERSION_CODE = 1;public static final String VERSION_NAME = "1.0";
}

或(我暂时使用的方法)

package com.hoho.android.usbserial;public final class BuildConfig {public static final boolean DEBUG = org.qtproject.example.BuildConfig.DEBUG;public static final String APPLICATION_ID = org.qtproject.example.BuildConfig.APPLICATION_ID;public static final String BUILD_TYPE = org.qtproject.example.BuildConfig.BUILD_TYPE;public static final int VERSION_CODE = org.qtproject.example.BuildConfig.VERSION_CODE;public static final String VERSION_NAME = org.qtproject.example.BuildConfig.VERSION_NAME;
}
4) 定义包自身的gradle, 这个我暂时没有去Study和尝试, 懂得朋友开始自己的表演。(推荐)

6. 代码

mainwindows.cpp

void MainWindow::test()
{QJniObject str = QJniObject::fromString(ui->cbPortNames->currentText());jboolean res = QJniObject::callStaticMethod<jboolean>("usb/USBListActivity","test","(Ljava/lang/String;)Z",str.object<jstring>());if (0 == res){logger("test failed");}else{logger("test succeed");}
}

usb.USBListActivity.java

package usb;import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.io.IOException;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 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);// getDeviceList();}public static boolean test(String portName){System.out.println("<-------------->test: " + portName);if (portName.isEmpty()){Log.i(tag, "port empty");return false;}System.out.println("<-------------->test1: " + portName);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;}Ch34xSerialDriver ch340Device = new Ch34xSerialDriver(device);UsbSerialPort serialport = ch340Device.getPorts().get(0);/* 打开串口 */try {serialport.open(deviceConnection);} catch (IOException ignored) {Log.i(tag, "fail to open serial port");return false;}/* 设置串口参数 */try {serialport.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);}catch (IOException ignored) {Log.i(tag, "fail to set parameters");}/* 向串口发送数据 */try {serialport.write("Hello, world!".getBytes(), 1000);} catch (IOException e) {System.out.println("catched write error expected");}/* 关闭串口 */try {serialport.close();} catch (IOException ignored) {}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------------------------->");}
}

7. 连线

  1. PC 和 手机端各接一个USB转TTL线
    RX<->TX
    TX<->RX
    GND<->GND

8. 运行

第一次申请权限时同意了但还是判定失败, 后续解决,第二次执行test时成功…

手机端显示
在这里插入图片描述
PC端串口打印
在这里插入图片描述


帮助文档

Qt for Android

Qt for android 文档(thinkinginqt.com)
Qt for android 官方文档(Qt6.2LTS)
Qt Project to Manifest Configuration

Android

UsbManager(apiref.com)
UsbManager android-doc.com
UsbManager(matools.com)
Activity 生命周期概念

其他文章

Qt for android 获取USB设备列表(一)Java方式 获取
Qt for android 获取USB设备列表(二)JNI方式 获取
Qt for Android 乱码问题

相关文章:

  • 国产32位MCU的发展与机遇
  • 【数组】Leetcode 57. 插入区间【中等】
  • 【计算机视觉(2)】
  • 【LeetCode算法】第83题:删除排序链表中的重复元素
  • 一文搞透常见的Python编码陷阱(上)(分析+案例)
  • 如何判断一个对象是否已经被回收?
  • C++ 常用UI库
  • 如何消除*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS。如何消除函数未使用的警告
  • HTTPS能否避免流量劫持?如何实现HTTPS
  • 正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-24.1,2 SPI驱动实验-SPI协议介绍
  • 【软件测试】bug篇|软件测试的生命周期|描述bug的要素|bug的级别|bug的生命周期|高频面试题:与开发产⽣争执怎么处理
  • SSL VPN
  • C++系列-定位new表达式(placement-new)
  • 一个程序员的牢狱生涯(40)好事
  • 谈谈BlueStore的BitmapAllocator
  • [PHP内核探索]PHP中的哈希表
  • #Java异常处理
  • [deviceone开发]-do_Webview的基本示例
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • ES10 特性的完整指南
  • Git学习与使用心得(1)—— 初始化
  • Java Agent 学习笔记
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • SQLServer之索引简介
  • 多线程事务回滚
  • 解析 Webpack中import、require、按需加载的执行过程
  • 三栏布局总结
  • 微信小程序--------语音识别(前端自己也能玩)
  • 系统认识JavaScript正则表达式
  • 与 ConTeXt MkIV 官方文档的接驳
  • 你对linux中grep命令知道多少?
  • #HarmonyOS:基础语法
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1)STL算法之遍历容器
  • (55)MOS管专题--->(10)MOS管的封装
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (小白学Java)Java简介和基本配置
  • (一)Docker基本介绍
  • (一)UDP基本编程步骤
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • 、写入Shellcode到注册表上线
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .Net - 类的介绍
  • .net SqlSugarHelper
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • ??eclipse的安装配置问题!??
  • @Autowired自动装配
  • @Transient注解
  • [ C++ ] STL---string类的模拟实现
  • [ NOI 2001 ] 食物链
  • [20160902]rm -rf的惨案.txt