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

Android框架下获取SD卡容量始终为0的解决方法

解决SD卡容量获取始终为0的问题

1. 权限适配

Android 10(API 29)及以上版本,访问SD卡需要申请MANAGE_EXTERNAL_STORAGE权限(需在Manifest声明并引导用户手动开启);Android 9及以下需申请READ_EXTERNAL_STORAGE权限。

Manifest声明:

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

动态申请权限逻辑:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivity(intent);
    }
} else {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE);
}

2. 使用StorageVolumeStats API获取准确容量

不要依赖File.getTotalSpace()或File.getFreeSpace(),改用StorageManager提供的StorageVolumeStats接口获取SD卡容量:

// 替换原代码中totalBytes和usableBytes的获取逻辑
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    try {
        StorageVolumeStats stats = storage.getVolumeStats(storageVolume.getUuid());
        long totalBytes = stats.getTotalBytes();
        long usableBytes = stats.getAvailableBytes();
        Slog.d(TAG, "sdcard totalBytes:" + totalBytes);
        Slog.d(TAG, "sdcard usableBytes:" + usableBytes);
    } catch (IOException e) {
        Slog.e(TAG, "获取SD卡容量失败", e);
    }
}

3. 修正StorageVolume筛选逻辑

确保筛选的是真正的可移除SD卡:

  • 增加!volume.isPrimary()判断,排除内部存储(内部存储isPrimary()返回true)
  • Android 10+用getDirectory()替代getPathFile()获取实际可访问目录:
for (StorageVolume volume : list) {
    boolean removable = volume.isRemovable();
    String vlState = volume.getState();
    // 排除内部存储,只保留可移除且已挂载的SD卡
    if (removable && !volume.isPrimary() && vlState.equals(Environment.MEDIA_MOUNTED)) {
        exist = true;
        storageVolume = volume;
    }
}

// 获取实际目录
File sdCardDir = storageVolume.getDirectory();
if (sdCardDir != null && sdCardDir.exists()) {
    // 后续操作
}

4. 检查SD卡挂载模式

部分设备支持将SD卡格式化为“内部存储”,此时SD卡会被识别为内部存储的一部分,isRemovable()会返回false。需在设备设置中确认SD卡处于“可移动存储”模式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:33:20