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

Android获取SD卡路径问题:已获全文件权限仍无法访问外置SD卡

问题:Android 11+下获取外置SD卡绝对路径用于照片整理

我正在开发一款自用的照片整理APP,需求是按照片创建日期将其分类到2023-01、2023-02这类命名的文件夹中。照片存储在外置SD卡,但目前无法访问该SD卡:已授予ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION权限,但以下方法均无法获取SD卡真实路径:

  • context.getExternalFilesDirs(null) 返回的数组中有一个元素为null;
  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) 指向内部存储;
  • File("/sdcard") 实际访问的是内部存储而非SD卡。

我需要获取类似/storage/7B32-B4556/这样的真实SD卡路径。也曾尝试调用以下代码选择SD卡目录,但得到的是模糊的content URI,且无法从中获取绝对文件路径,我不想使用存储API:

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
chooseDirectoryRequestLauncher.launch(intent)

项目API配置

compileSdk 34

defaultConfig {
    applicationId "com.cndgf.photosorter"
    minSdk 30
    targetSdk 34
    versionCode 1
    versionName "1.0"
}

Manifest权限配置

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.PERMISSIONS_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_EXTERNAL_STORAGE" />

解决方案

1. 清理无效权限

Manifest中的PERMISSIONS_STORAGE和REQUEST_EXTERNAL_STORAGE并非Android官方定义的权限,直接删除即可。保留MANAGE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE三个有效权限。

2. 获取外置SD卡真实路径的可行代码

在Android 10+环境下,拥有MANAGE_EXTERNAL_STORAGE权限时,可通过系统存储服务遍历挂载卷获取SD卡路径:

fun getExternalSdCardPath(context: Context): String? {
    val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val storageVolumes = storageManager.storageVolumes
    for (volume in storageVolumes) {
        // 跳过内部存储
        if (volume.isPrimary) continue
        // 仅处理已挂载的可访问卷
        if (volume.state == Environment.MEDIA_MOUNTED) {
            val path = volume.directory?.absolutePath
            if (path != null && path.startsWith("/storage/")) {
                return path
            }
        }
    }
    return null
}

3. 确保权限已正确授予

MANAGE_EXTERNAL_STORAGE权限需要用户手动到系统设置开启,需在代码中检查并引导:

// 检查权限状态
fun hasManageStoragePermission(context: Context): Boolean {
    return Environment.isExternalStorageManager()
}

// 引导用户开启权限
fun requestManageStoragePermission(context: Context) {
    val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
    intent.data = Uri.parse("package:${context.packageName}")
    context.startActivity(intent)
}

4. 关键注意事项

  • 部分设备SD卡路径格式可能略有差异,但StorageVolume.directory返回的是系统认可的真实可访问路径;
  • 操作前需确认SD卡处于MEDIA_MOUNTED状态,避免读写失败;
  • 禁止硬编码SD卡路径,不同厂商设备挂载路径可能存在区别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:52:59