You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt 6 Android 11应用读写文件权限被拒问题求助

解决Qt 6 + Android 11(SDK 31)下Widget应用的TXT文件写入权限问题

问题背景

基于Qt 6、CMake开发面向Android 11(SDK 31)的Widget应用,当前遇到.txt文件写入权限被拒的问题——应用可以创建.txt文件,但无法写入内容。

已尝试的无效方案

  • 通过QJniObject调用isExternalStorageManager检查权限,未授权时跳转至全文件权限设置页,但该设置项呈灰色,无法开启
  • 递归请求android.permission.MANAGE_EXTERNAL_STORAGE权限,同时试过READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE以及QtAndroidPrivate::Storage相关方法,均无效果
  • 尝试申请android.permission.MANAGE_DOCUMENTS权限,问题依旧

报错信息

return (<E Qt JAVA : openParcelFdForContentUrl: java.lang.SecurityException: Permission Denial: writing com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/62.txt from pid=2455, uid=10179 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()>
)

相关代码

QString filename = QFileDialog::getSaveFileName();
filename = filename + ".txt";
qDebug() << "the file name is : " + filename;
ui->startPageProgramName->setText(test.toString());
auto result = QtAndroidPrivate::checkPermission("android.permission.MANAGE_DOCUMENTS").result();
if(result == QtAndroidPrivate::PermissionResult::Denied){
    result = QtAndroidPrivate::requestPermission(QString("android.permission.MANAGE_DOCUMENTS")).result();
}
QFile file(filename);
if(!file.open(QIODevice::WriteOnly)){
    qDebug() << file.errorString();
    return;
}else{
    QTextStream out(&file);
    out << "QString::fromStdString(mainPro_->programToString())";
    qDebug() << &out;
    out.flush();
    out << "testing som more";
    out << "agian";
    file.close();
}

解决方向

  1. 适配Android分区存储规则:Android 11起强制分区存储,MANAGE_EXTERNAL_STORAGE权限仅对文件管理器等特定类型应用开放,普通应用无法正常获取。如果你的应用不属于这类,别再死磕这个权限,转而用以下几种方式:
    • 应用专属目录:写入应用私有目录(无需额外权限),Qt可通过QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)获取该路径
    • MediaStore:如果是媒体类文件,通过MediaStore API写入公共媒体目录
    • SAF存储访问框架:通过SAF获取的URI需要用Android原生API写入,不能直接用Qt的QFile操作
  2. 正确处理SAF返回的URI:你用QFileDialog::getSaveFileName()拿到的是content URI,不是本地文件路径,QFile直接操作会触发权限问题。需要通过JNI调用Android的ContentResolver来写入:
    • 把QString类型的URI转为Android的Uri对象
    • 获取App的ContentResolver实例
    • 调用openOutputStream(Uri)获取输出流,再把数据写入这个流
  3. 放弃无效权限申请:MANAGE_DOCUMENTS是系统级权限,普通应用根本申请不到,不用再尝试。
  4. 配置清单文件:在AndroidManifest.xml中正确声明权限,同时可添加android:requestLegacyExternalStorage="true"作为临时过渡方案(长期还是建议适配分区存储)。

内容的提问来源于stack exchange,提问作者rasmus klitgaard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:25:23