Qt for android : 简单实现弹窗创建文件,并使用JNI进行读写实例

news/2025/1/16 19:11:09/

简介

Qt版本 : Qt6.6.2
手机: RedMi 7A
本例使用JNI方式打开窗体创建文件, handleActivityResult中处理创建文件之后通过InputStream/OutputStream简单读写文件

代码

项目添加

QT += core-private

头文件

代码来之参考中的连接, 稍微修改
需要注意的是 QAndroidActivityResultReceiver, 继承之后可以接收startActivity执行之后的返回结果,handleActivityResult槽中处理结果

#ifndef HARDWAREUTILS_ANDROID_H
#define HARDWAREUTILS_ANDROID_H#include "private/qandroidextras_p.h"
#include "qjniobject.h"
#include <QObject>
#include <QJniObject>
#include <QJniEnvironment>
#include <QFile>class HardwareUtilsAndroid: public QObject, public QAndroidActivityResultReceiver
{
private:HardwareUtilsAndroid(QObject *parent = 0);public:virtual ~HardwareUtilsAndroid();static HardwareUtilsAndroid* Instance(QObject *parent = 0);virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject & data);virtual bool writeOnUSB(QString filename);private:void writeFile(QJniObject &fileUri, const QString &text);void readFile(QJniObject &fileUri, QString &text);private:QFile m_file;
};#endif // HARDWAREUTILS_ANDROID_H

源文件


#include "HardwareUtils_Android.h"
#include <jni.h>#include <QDebug>HardwareUtilsAndroid *HardwareUtilsAndroid::Instance(QObject *parent) {static HardwareUtilsAndroid *instance = NULL;if(!instance) {instance = new HardwareUtilsAndroid(parent);}return instance;
}HardwareUtilsAndroid::HardwareUtilsAndroid(QObject *parent):QObject(parent)
{
}HardwareUtilsAndroid::~HardwareUtilsAndroid()
{
}bool HardwareUtilsAndroid::writeOnUSB(QString filename) 
{QJniObject ACTION_CREATE_DOCUMENT = QJniObject::fromString("android.intent.action.CREATE_DOCUMENT");QJniObject intent("android/content/Intent");if (ACTION_CREATE_DOCUMENT.isValid() && intent.isValid()) {intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", ACTION_CREATE_DOCUMENT.object<jstring>());intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJniObject::fromString("text/plain").object<jstring>());intent.callObjectMethod("putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",QJniObject::fromString("android.intent.extra.TITLE").object<jstring>(),QJniObject::fromString(filename).object<jstring>());QtAndroidPrivate::startActivity(intent.object<jobject>(), 123, this);return true;} else {return false;}
}void HardwareUtilsAndroid::writeFile(QJniObject &fileUri, const QString &text)
{// 获取文件输出流QJniObject activity = QtAndroidPrivate::activity();QJniObject contentResolver = activity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");QJniObject outputStream = contentResolver.callObjectMethod("openOutputStream", "(Landroid/net/Uri;)Ljava/io/OutputStream;",fileUri.object<jobject>());if (outputStream.isValid()){QJniObject stringToWrite = QJniObject::fromString(text);QJniObject bytes = stringToWrite.callObjectMethod("getBytes", "()[B");QJniEnvironment env;jbyteArray byteArray = static_cast<jbyteArray>(bytes.object<jarray>());jbyte* byteData = env->GetByteArrayElements(byteArray, nullptr);int length = env->GetArrayLength(byteArray);outputStream.callMethod<void>("write", "([B)V", byteArray);env->ReleaseByteArrayElements(byteArray, byteData, 0);outputStream.callMethod<void>("close", "()V");qDebug() << "File written successfully";}else{qDebug() << "Failed to open output stream";}
}void HardwareUtilsAndroid::readFile(QJniObject &fileUri, QString &text)
{QJniEnvironment env;QJniObject activity = QtAndroidPrivate::activity();QJniObject contentResolver = activity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");// 创建InputStreamQJniObject inputStream = contentResolver.callObjectMethod("openInputStream", "(Landroid/net/Uri;)Ljava/io/InputStream;", fileUri.object<jobject>());// 创建缓冲区jbyteArray bufferArray = env->NewByteArray(1024);// 读取数据QByteArray fileData;jint bytesRead;while ((bytesRead = inputStream.callMethod<jint>("read", "([B)I", bufferArray)) != -1) {jbyte* buffer = env->GetByteArrayElements(bufferArray, nullptr);fileData.append(reinterpret_cast<const char*>(buffer), bytesRead);env->ReleaseByteArrayElements(bufferArray, buffer, JNI_ABORT);}// 关闭流if (inputStream.isValid()) {inputStream.callMethod<void>("close", "()V");if (env->ExceptionCheck()) {env->ExceptionClear();}}text = QString::fromUtf8(fileData);// 删除局部引用env->DeleteLocalRef(bufferArray);
}void HardwareUtilsAndroid::handleActivityResult(int receiverRequestCode, int resultCode, const QJniObject & data) 
{qDebug() << "Receive activity result";jint RESULT_OK = QJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK");if (receiverRequestCode == 123 && resultCode == RESULT_OK){QJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;");if (!uri.isValid()){qDebug() << "Invalid URI";return;}QString text;writeFile(uri, QString("hello world!!!!"));readFile(uri, text);qDebug() << "read: " << text;}else{qDebug() << "Failed to create file";}
}

调用

可以搭配QFileDialog进行使用,打开U盘的路径创建文件

HardwareUtilsAndroid::Instance()->writeOnUSB(dlg.selectedFiles().value(0));

参考:
https://github.com/jbflamant/android-usb-access


http://www.ppmy.cn/news/1563687.html

相关文章

linux 用户权限管理

1.建立用户目录&#xff0c;创建目录/tech/benet、/tech/accp&#xff0c;分别用于不同项目组 mkdir -p /tech/benetmkdir -p /tech/accp 2.添加组帐号benet、accp&#xff0c;GID号分别设置为2001、2002 3.为技术部添加组帐号tech&#xff0c;GID号设置为200 使用cat /etc/gr…

CES Asia 2025科技创新奖申报火爆,AI企业成主力军

随着CES 2025上人工智能大放异彩&#xff0c;CES Asia 2025&#xff08;赛逸展&#xff09;科技创新奖的申报也迎来了热潮&#xff0c;尤其是AI人工智能企业&#xff0c;申报数量大幅增加。 自CES Asia 2025科技创新奖申报工作启动以来&#xff0c;截至[具体日期]&#xff0c;…

庖丁解java(一篇文章学java)

(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念... 当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢? 请看下文... 关于决定开始写博文的介绍 …

如何Python机器学习、深度学习技术提升气象、海洋、水文?

一&#xff1a;Python软件的安装 1.1 Python在气象中的应用 1.2 Anaconda解释和安装以及Jupyter配置 1.3 Python基础语法 二&#xff1a;气象常用科学计算库 2.1 Numpy库 2.2 Pandas库 2.4 Xarray库 三&#xff1a;气象海洋常用可视化库 3.1可视化库介绍Matplotlib、Ca…

24. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--预算扣除、退回、补充

这篇文章我们一起来编写目前为止最为复杂的功能&#xff1a;预算扣除、退回、补充。预算回退有三种情况&#xff1a;修改后的支出金额小于修改前的支出金额、支出记录删除后、记录类型从支出改为收入。预算补充的情况有两种&#xff1a;记录类型从收入改为支出、修改后的支出金…

你喜欢用什么编辑器?

电脑工作者和程序员所使用的文本编辑器通常需要具备高效率、易用性以及对代码友好等特点&#xff0c;包括语法高亮、自动完成、多文件同时编辑、查找替换、版本控制集成等功能。以下是几个广受开发者欢迎且实用性较强的文本编辑器&#xff1a; Visual Studio Code&#xff08;V…

Thrustmaster Hotas Warthog飞行操作杆开发

目录 0 摘 要 &#xff1a;简单说一下这篇文章在搞啥 1 背 景 &#xff1a;什么需求以及对开发的背景调查 2 环境配置 &#xff1a;具体需要什么环境&#xff0c;对软件层面的需求 3 硬件测试 &#xff1a;测试遥感器…

【C语言】线程----同步、互斥、条件变量

目录 3. 同步 3.1 概念 3.2 同步机制 3.3 函数接口 1. 同步 1.1 概念 同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情 1.2 同步机制 通过信号量实现线程间的同步 信号量&#xff1a;通过信号量实现同步操作&#xff1b;由信号量来决定…