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

Scoped Storage(Java):如何检测应用是否使用legacy旧版存储

Scoped Storage Legacy模式检测及自动切换方案

核心检测方法

你可以通过官方API加实际读写校验两层逻辑来判断legacy存储是否可用:

  1. 官方API判断
    Android 10(API 29)及以上系统提供了Environment.isExternalStorageLegacy()方法,返回true代表当前应用正运行在legacy旧存储模式,返回false代表已启用分区存储。

注意事项:

  • preserveLegacyExternalStorage="true"仅对Android 10系统上从旧版本覆盖安装的应用生效,Android 11及以上系统该配置仅用于临时保留legacy权限,新安装的应用无论加什么配置都默认启用分区存储
  • Android 9及以下系统默认全程使用legacy存储,不需要额外判断
  • preserveLegacyExternalStorage属于过渡配置,Android 12及以上系统已完全废弃,所有应用最终都需要完成分区存储适配
  1. 兜底读写校验
    为了避免部分厂商定制ROM对API的修改导致判断异常,建议加一层实际读写公共目录的校验逻辑,尝试对Download等公共目录写入临时文件,操作成功则代表legacy权限有效。

自动切换实现逻辑

你可以按照如下流程实现模式自动切换:

  • 运行时先判断系统版本:
    • API < 29:直接走原有legacy存储逻辑
    • API >=29:先调用Environment.isExternalStorageLegacy()获取初步结果
  • 基于初步结果调用公共目录读写校验方法,确认legacy权限真实有效
  • 如果确认legacy权限失效,自动切换到已经适配的Scoped Storage逻辑

代码示例

// 第一层API判断
fun isLegacyStorageEnabled(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        Environment.isExternalStorageLegacy()
    } else {
        true
    }
}

// 第二层兜底校验
fun isLegacyStorageActuallyAvailable(): Boolean {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return true
    return try {
        val testFile = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), 
            "legacy_test_${System.currentTimeMillis()}.tmp"
        )
        // 尝试写入测试内容
        testFile.outputStream().use { it.write("test".toByteArray()) }
        // 尝试读取验证
        val content = testFile.inputStream().readBytes().toString(Charsets.UTF_8)
        // 删除测试临时文件
        testFile.delete()
        content == "test"
    } catch (e: SecurityException) {
        false
    } catch (e: IOException) {
        false
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:06:05