非系统级Android应用如何获取U盘容量?
获取/mnt/media_rw路径下U盘容量的可行方案
针对非系统应用无法通过StatFs和MediaStore获取/mnt/media_rw下U盘容量的问题,有以下几种可行方案:
1. 使用Storage Access Framework (SAF) 用户授权访问
这是最合规且兼容性最好的方案,通过让用户手动选择U盘根目录获取访问权限,再通过DocumentFile获取容量数据:
实现步骤
- 启动SAF的目录选择界面:
private static final int REQUEST_CODE_PICK_USB = 1001; // 触发U盘选择 Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, REQUEST_CODE_PICK_USB);
- 在
onActivityResult中处理授权后的容量获取:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_PICK_USB && resultCode == RESULT_OK) { Uri treeUri = data.getData(); DocumentFile usbRoot = DocumentFile.fromTreeUri(this, treeUri); if (usbRoot != null) { long totalSpace = usbRoot.getTotalSpace(); long freeSpace = usbRoot.getFreeSpace(); // 此处处理总容量和可用容量数据 } } }
优缺点
- 优点:无需特殊权限,符合Android权限规范,适配绝大多数设备
- 缺点:需要用户手动操作选择U盘,无法后台自动获取
2. 解析系统挂载信息+执行df命令
通过读取系统挂载文件和执行shell命令获取容量,无需用户交互,但兼容性存在差异:
实现步骤
- 读取
/proc/mounts文件,找到/mnt/media_rw下对应的U盘挂载子目录(比如/mnt/media_rw/UsbDriveA) - 执行
df命令并解析输出结果:
try { String mountPath = "/mnt/media_rw/UsbDriveA"; // 替换为实际挂载路径 Process process = Runtime.getRuntime().exec("df " + mountPath); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String headerLine = reader.readLine(); // 跳过表头行 String dataLine = reader.readLine(); if (dataLine != null) { // 按空格分割,不同设备输出格式可能有差异,需适配 String[] segments = dataLine.split("\\s+"); // 示例:第二列为总块数,第四列为可用块数,每块默认1KB long totalBlocks = Long.parseLong(segments[1]); long freeBlocks = Long.parseLong(segments[3]); long totalSpace = totalBlocks * 1024; long freeSpace = freeBlocks * 1024; // 处理容量数据 } reader.close(); process.waitFor(); } catch (IOException | InterruptedException e) { e.printStackTrace(); }
优缺点
- 优点:无需用户交互,可后台尝试获取
- 缺点:
df命令输出格式因设备而异,部分厂商可能限制普通应用执行shell命令,兼容性较差
3. 申请MANAGE_EXTERNAL_STORAGE权限(Android 11+)
针对Android 11及以上系统,可申请全文件访问权限,直接通过StatFs访问/mnt/media_rw路径:
实现步骤
- 在Manifest中声明权限:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- 引导用户到设置页面开启权限:
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); }
- 权限获取后使用
StatFs:
String usbPath = "/mnt/media_rw/UsbDriveA"; StatFs statFs = new StatFs(usbPath); long totalSpace = statFs.getTotalBytes(); long freeSpace = statFs.getFreeBytes();
优缺点
- 优点:可直接访问U盘路径,获取方式简单
- 缺点:权限为特殊权限,需用户手动到设置开启,Google Play对该权限的审核严格,仅允许文件管理器类应用申请
内容的提问来源于stack exchange,提问作者风清扬
相关产品推荐
相关产品推荐

