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

Android如何通过编程识别可移动存储中的OTG设备

Android 区分可移除存储中SD卡与OTG设备的实现方案

你当前已完成了所有存储卷的遍历逻辑,系统原生公开API在Android 13(API 33)之前没有直接区分SD卡与OTG存储的标记,可通过以下方案实现区分:

方案1:Android 13+ 官方API判断

API 33 为StorageVolume类新增了isUsb()方法,可直接判断可移除存储是否为OTG设备:

  • 可移除存储中isUsb() == true:为OTG存储
  • 可移除存储中isUsb() == false:为SD卡

方案2:低版本兼容判断

低于API 33的系统可通过反射获取隐藏字段、匹配挂载路径特征的方式区分:

  1. 反射调用StorageVolume的isUsb()隐藏方法,大部分厂商ROM保留了该未公开方法
  2. 若反射失败,可判断存储路径关键词:OTG存储路径通常包含usb、usbotg等字段,SD卡路径通常包含sdcard、ext_sd等字段

修改后的实现代码

fun getAvailableAllStorageVolumes(context: Context): ArrayList<StorageDirectoryParcelable> {
    val volumes = ArrayList<StorageDirectoryParcelable>()
    val sm = context.getSystemService(StorageManager::class.java)

    for (volume in sm.storageVolumes) {
        val path = getVolumeDirectory(volume)
        val name = volume.getDescription(context)
        // 新增存储类型判断逻辑
        val storageType = when {
            volume.isPrimary || !volume.isRemovable -> "内部存储"
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
                if (volume.isUsb) "OTG存储" else "SD卡"
            }
            else -> {
                // 低版本反射判断isUsb
                var isUsb = false
                try {
                    val method = StorageVolume::class.java.getMethod("isUsb")
                    isUsb = method.invoke(volume) as Boolean
                } catch (e: Exception) {
                    // 反射失败则匹配路径
                    isUsb = path.path.contains("usb", ignoreCase = true)
                }
                if (isUsb) "OTG存储" else "SD卡"
            }
        }
        // 可将storageType存入你的StorageDirectoryParcelable实体类按需使用
        volumes.add(StorageDirectoryParcelable(path.path, name))

        Log.e("USB", "name:- $name")
        Log.e("USB", "存储类型:- $storageType")
        Log.e("USB", "isPrimary:- ${volume.isPrimary}")
        Log.e("USB", "isEmulated:- ${volume.isEmulated}")
        Log.e("USB", "isRemovable:- ${volume.isRemovable}")
        Log.e("USB", "state:- ${volume.state}")
    }
    return volumes
}

注意事项

  • 部分厂商定制ROM可能修改存储路径命名规则或隐藏系统方法,建议结合名称、路径、反射结果多维度判断,提升准确率
  • 访问存储前需要提前申请对应权限:Android 12及以下申请READ_EXTERNAL_STORAGE,Android 13及以上根据业务场景申请对应媒体权限或全文件访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 06:36:04