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

Android 11+下无法在可移除SD卡共享目录创建文件的技术咨询

Android 11+下QT C++应用SD卡共享目录写入方案

问题背景

开发面向Android 11+的QT C++应用,通过SAF让用户选择文件夹下载媒体文件:

  • 可正常操作的路径:
    • "/storage/emulated/0/Download/"(主外部共享存储)
    • "/storage/emulated/0/Android/data/com.app.app/files"(主应用私有存储)
    • "/storage/XXXX-XXXX/Android/data/com.app.app/files"(SD卡应用私有存储)
  • 无法操作的路径:
    • "/storage/XXXX-XXXX/Download/"(SD卡外部共享目录),报错Cannot create file: /storage/9016-4EF8/...
  • 核心矛盾:SD卡应用私有存储的文件无法被其他应用(图库、编辑器等)访问,主存储容量不足的用户需要将可被其他应用访问的文件存到SD卡

可行解决方案

1. 基于SAF Uri操作文件(推荐)

Android 11+对SD卡共享目录的写入必须通过SAF的DocumentFile API,不能直接用标准C++路径读写。QT中需通过JNI桥接实现:

  • 用户通过SAF选择SD卡共享目录后,保存返回的Uri(而非路径字符串)
  • 写入文件时,通过JNI调用DocumentFile.createFile()创建目标文件,再用ContentResolver.openOutputStream()获取输出流,将下载内容写入
  • 此方式创建的文件位于共享目录,其他应用可正常访问,且符合Android权限规范

2. 申请MANAGE_EXTERNAL_STORAGE权限(限特定场景)

若应用属于文件管理器、备份类等符合Google Play权限政策的类型,可申请全文件访问权限:

  • 在AndroidManifest.xml中添加权限声明:<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  • 引导用户到系统设置授予权限:通过Intent(ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)跳转
  • 获权后可直接用标准C++函数(如std::ofstream、fopen)读写SD卡共享目录
  • 注意:非合规应用申请此权限会被Google Play拒绝上架

3. 用MediaStore API存储媒体文件(仅适用于媒体类文件)

如果下载的是图片、视频、音频等媒体文件,可通过MediaStore API插入到SD卡的媒体集合:

  • 通过JNI调用ContentResolver.insert(),指定存储位置为SD卡的媒体目录(如MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
  • 获取插入后的Uri,打开输出流写入文件内容
  • 该方式创建的文件会被系统媒体库自动索引,图库等应用可直接识别访问

QT C++实现注意事项

  • 禁止直接用标准C++文件操作函数访问SD卡共享目录路径,必须通过JNI桥接Android原生API
  • 封装JNI工具类,提供createFileFromUri、writeStreamToUri等接口供QT代码调用
  • 对用户选择的SAF目录Uri,调用takePersistableUriPermission获取持久权限,避免应用重启后丢失访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:40:25