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

适配Android 13外部存储:作用域存储实现及其他方案咨询

Android 13 存储适配方案及作用域存储实现

可选补充方案

  • 文件分享(File Provider):针对你提到的方案1(应用专属外部目录),其实可以通过File Provider给外部应用授权访问特定文件,无需暴露整个目录,是官方推荐的跨应用文件共享方式,且无需额外的存储权限。
  • MediaStore 媒体文件共享:如果你的文件属于图片、音频、视频等媒体类型,可通过MediaStore将文件插入公共媒体集合,外部应用可直接访问这些媒体文件。

方案3:在外部/Documents下创建应用专属文件夹(作用域存储)实现

Android 11+的作用域存储中,要在/Documents目录下创建应用专属文件夹,需通过系统目录选择器获取用户授权,再进行文件夹创建,具体步骤如下:

1. 请求用户授权访问Documents目录

启动系统目录选择器,引导用户选择Documents目录:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(intent, REQUEST_CODE_DOCUMENTS_DIR)

在回调中获取目录Uri并持久化权限(避免重启后丢失授权):

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == REQUEST_CODE_DOCUMENTS_DIR && resultCode == Activity.RESULT_OK) {
        data?.data?.let { treeUri ->
            // 持久化Uri读写权限
            contentResolver.takePersistableUriPermission(
                treeUri,
                Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
            )
            // 创建应用专属文件夹
            createAppFolder(treeUri)
        }
    }
}

(若使用AndroidX,推荐用registerForActivityResult替代startActivityForResult)

2. 创建应用专属文件夹

通过DocumentsContract.createDocument在选定的Documents目录下创建子文件夹:

private fun createAppFolder(treeUri: Uri) {
    val appFolderName = "MyAppFiles" // 替换为你的应用文件夹名称
    val folderUri = DocumentsContract.createDocument(
        contentResolver,
        treeUri,
        DocumentsContract.Document.MIME_TYPE_DIR,
        appFolderName
    )
    // folderUri即为创建好的应用文件夹Uri,后续可通过此Uri管理文件夹内的文件
}

3. 在文件夹内创建并操作文件

拿到文件夹Uri后,可创建具体文件并写入内容:

fun createFileInFolder(folderUri: Uri, fileName: String, mimeType: String): Uri? {
    return DocumentsContract.createDocument(
        contentResolver,
        folderUri,
        mimeType,
        fileName
    )
}

// 示例:创建并写入文本文件
val fileUri = createFileInFolder(folderUri, "note.txt", "text/plain")
fileUri?.let {
    contentResolver.openOutputStream(it)?.use { outputStream ->
        outputStream.write("Hello World".toByteArray())
    }
}

方案1补充:应用专属外部目录的跨应用访问

若你倾向使用应用专属外部目录(getExternalFilesDir(null)),可通过File Provider实现外部应用访问:

  1. 在AndroidManifest.xml注册File Provider:
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.yourpackage.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  1. 在res/xml下创建file_paths.xml配置共享目录:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="external_files" path="." />
</paths>
  1. 生成共享Uri并启动外部应用编辑:
val targetFile = File(getExternalFilesDir(null), "edit_me.txt")
val shareUri = FileProvider.getUriForFile(this, "com.yourpackage.fileprovider", targetFile)
val editIntent = Intent(Intent.ACTION_EDIT).apply {
    setDataAndType(shareUri, "text/plain")
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivity(editIntent)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:04:53