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,提问作者林一一
相关产品推荐
相关产品推荐

