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

API 29+ Android作用域存储:如何判断足够可用媒体存储空间?

Android API 29+ 作用域存储下判断公共存储磁盘空间的方案

在API 29及以上的作用域存储规则下,无法通过File API直接操作公共存储目录,要判断音乐目录所在的外部存储是否有足够空间存放媒体文件,可通过StorageManager API实现,具体步骤如下:

  • 1. 定位目标存储卷
    公共音乐目录对应的MediaStore URI为MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,先通过这个URI获取其所属的存储卷对象:

    val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
    val audioPublicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
    val targetVolume = storageManager.getStorageVolume(context.contentResolver, audioPublicUri)
    
  • 2. 获取可用空间(准确值)
    拿到存储卷后,使用getAllocatableBytes()方法获取应用实际可使用的空间(该方法会扣除系统预留的空间,比getFreeBytes()更可靠):

    targetVolume?.uuid?.let { volumeUuid ->
        val requiredSpace = 100 * 1024 * 1024L // 服务器告知的100MB文件大小
        val availableSpace = storageManager.getAllocatableBytes(volumeUuid)
        
        // 建议预留少量额外空间,应对元数据或写入开销
        val safeRequiredSpace = requiredSpace * 1.1.toLong()
        
        if (availableSpace >= safeRequiredSpace) {
            // 空间充足,可执行下载和写入MediaStore操作
        } else {
            // 空间不足,提示用户清理存储
        }
    } ?: run {
        // 外部存储不可用(如SD卡移除),提示用户
    }
    
  • 3. 权限说明

    • API 29-32:需声明WRITE_EXTERNAL_STORAGE权限(无需动态申请,因为是写入公共媒体目录)
    • API 33+:无需额外写入权限,只需声明对应媒体类型的读取权限(如READ_MEDIA_AUDIO),即可通过MediaStore写入公共音乐目录
    • getAllocatableBytes()方法在API 26及以上可用,无需特殊权限(只要应用有权限写入目标存储卷即可)

关键注意点

  • 禁止使用Environment.getExternalStorageDirectory()等废弃API,这类方法在作用域存储下无法访问公共目录
  • 务必用getAllocatableBytes()而非getFreeBytes(),后者返回的总空闲空间包含系统预留的不可用部分,会导致误判
  • 写入时直接通过MediaStore打开OutputStream写入,无需先下载到内部存储再复制,节省额外空间占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:15:05