为什么此代码错误地报告了我的Android设备上的可用空间?

我的带有32GB SD卡的三星X-Cover2 GT-S7710在设置>存储中报告了正确的空间,但是使用此代码只有0.6 GB或如何检查安装在Android设备上的SD卡有多少可用空间? :

sdStorageDirectory = Environment.getExternalStorageDirectory().getPath(); StatFs statSd = new StatFs(sdStorageDirectory); Log.d(TAG, "gb available " + String.valueOf((double) (statSd.getAvailableBlocks() * statSd.getBlockSize()) / 1073741824)); 

为什么会这样,我怎样才能正确发现真正的自由空间?

这种行为的原因可能是在手机的情况下,SD卡不被视为主要的外部存储设备。 getExternalStorageDirectory()的描述解释了这个:

注意:这里不要混淆“外部”这个词。 此目录可以更好地被视为媒体/共享存储。 它是一个文件系统,可以容纳相对大量的数据,并在所有应用程序之间共享(不强制执行权限)。 传统上,这是一张SD卡,但它也可以在与受保护的内部存储不同的设备中实现为内置存储,并且可以作为文件系统安装在计算机上。

所以你可能会得到一些真正0.6 GB的系统。

幸运的是,您正在寻找的设备安装在与您获得的设备相同的父目录中的可能性非常高。 首先,我将检查这是否是您正在寻找的设备,如isExternalStorageRemovable() ,如果不是这样,请尝试同一父目录中的其他设备:

 File sdStorage; if(sdStorage.isExternalStorageRemovable()) { sdStorage = Environment.getExternalStorageDirectory(); } else { List storages = Environment.getExternalStorageDirectory().getParentFile().listFiles(); for(File storage : storages) { if(! storages.equals(Environment.getExternalStorageDirectory()) { sdStorage = storage; break; } } } if(sdStorage == null) { // No non-removable storage device was found } 

这假设只安装了两个设备。 在极少数情况下,这可能不是真的(例如,因为通过USB-OTG安装了另一个存储设备); 你必须在这里找到另一种解决方法。 一个想法可能是通过一个过程运行这里描述的mount命令,并通过这些结果找到正确的设备。 然而,这将变得非常复杂。 它还假设所有外部存储设备都安装在同一个父目录下(通常是/mnt/ )。 如果不是这样的话, mount命令再一次是你最好的希望。

编辑1:可能有一些设备挂载到/sdcard而不使用/mnt目录(尽管在某些情况下可能是对/mnt/sdcard的引用,在这种情况下你会没事的)。 所以在这些情况下你必须使用mount的输出。

编辑2:我检查并发现,在我的手机上/mnt包含了不少目录,我只想要其中一个。 所以我提出了这个解决方案而不是上面的解决方案:

 File sdStorage; if(sdStorage.isExternalStorageRemovable()) { sdStorage = Environment.getExternalStorageDirectory(); } else { Process process = null; Scanner scan = null; try { process = new ProcessBuilder().command("ls", "-l", sdStorage.getParent()).redirectErrorStream(true).start(); scan = new Scanner(process.getInputStream()); while(scan.hasNextLine()) { String line = scan.nextLine(); String[] parts = line.split("\\s"); if(parts.length > 2 && parts[2].equals("sdcard_rw") && ! Environment.getExternalStorageDirectory().equals(Environment.getExternalStorageDirectory().getParent() + File.seperator + parts[3]) { sdStorage = new File(Environment.getExternalStorageDirectory().getParent() + File.seperator + parts[3]); break; } } catch(IOException e) { // Do something here } finally { if(scan != null) scan.close(); if(process != null) process.destroy(); } } } 

这里的背景是,所有外部存储设备似乎都属于用户sdcard_rw因此这是我们可以检查的内容。 遗憾的是,在Android中检查文件所有权的最短方法似乎是……嗯,不是很直观。 但希望这应该独立于各种存储设备的安装位置。

尝试这个:

 StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount(); long megAvailable = bytesAvailable / 1048576; System.out.println("Megs :"+megAvailable); 

getBlockCount() – 返回SD卡的大小; getAvailableBlocks() – 返回正常程序仍可访问的块数

此链接中的详细信息