我想以编程方式获取设备内部/外部存储空闲内存的大小.我正在使用这段代码:
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Log.e("","Available MB : "+megAvailable);
File path = Environment.getDataDirectory();
StatFs stat2 = new StatFs(path.getPath());
long blockSize = stat2.getBlockSize();
long availableBlocks = stat2.getAvailableBlocks();
String format = Formatter.formatFileSize(this, availableBlocks * blockSize);
Log.e("","Format : "+format);
Run Code Online (Sandbox Code Playgroud)
而我得到的结果是:
11-15 10:27:18.844: E/(25822): Available MB : 7572
11-15 10:27:18.844: E/(25822): Format : 869MB
Run Code Online (Sandbox Code Playgroud)
问题是我想获得1,96GB现在的SdCard的免费记忆.如何修复此代码,以便获得免费大小?
Google不幸地计划破坏存储权限,以使应用程序无法使用标准File API(和文件路径)访问文件系统。许多人反对它,因为它改变了应用程序访问存储的方式,并且在许多方面都是受限制的有限API。
因此,如果我们想处理各种问题,我们将需要在将来的某些Android版本上完全使用SAF(存储访问框架)(在Android Q上,我们至少可以暂时使用一个标志来使用常规存储权限)。存储卷并到达那里的所有文件。
因此,例如,假设您要制作一个文件管理器并显示设备的所有存储卷,并为每个文件显示有多少总字节和可用字节。这样的事情看起来非常合法,但是由于我找不到找到这种方法的方法。
从API 24(此处)开始,我们终于可以列出所有存储卷,如下所示:
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
Run Code Online (Sandbox Code Playgroud)
事实是,此列表上的每个项目都没有功能来获取其大小和可用空间。
但是,以某种方式,Google的“ Google提供的文件”应用程序设法获得了该信息,而没有获得任何形式的许可:
并在装有Android 8的Galaxy Note 8上进行了测试。甚至没有最新版本的Android。
因此,这意味着即使在Android 8上,也应该有一种无需任何许可即可获取此信息的方法。
有一些类似于获得自由空间的东西,但是我不确定是否确实如此。虽然如此。这是它的代码:
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
AsyncTask.execute {
for (storageVolume in storageVolumes) {
val uuid: UUID = storageVolume.uuid?.let { UUID.fromString(it) } ?: StorageManager.UUID_DEFAULT
val allocatableBytes = storageManager.getAllocatableBytes(uuid)
Log.d("AppLog", "allocatableBytes:${android.text.format.Formatter.formatShortFileSize(this,allocatableBytes)}")
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我找不到类似的东西来获取每个StorageVolume实例的总空间。假设我对此是正确的,我已经在这里提出了要求。
您可以在我对此问题写的答案中找到更多我所找到的内容,但是目前,这是所有变通办法的结合,这些工作不是变通办法,而是在某些情况下有效。 …
这是我的代码,
private String memSize(String path){
StatFs stat = new StatFs(path);
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
long freeBlocks = stat.getFreeBlocks();
long countBlocks = stat.getBlockCount();
String fileSize = Formatter.formatFileSize(this, availableBlocks * blockSize);
String maxSize = Formatter.formatFileSize(this, countBlocks * blockSize);
String info = path.toString()
+ "\nblockSize : " + Long.toString(blockSize)
+ "\navailableBlocks : " + Long.toString(availableBlocks)
+ "\nfreeBlocks : " + Long.toString(freeBlocks)
+ "\nreservedBlocks : " + Long.toString(freeBlocks - availableBlocks)
+ "\ncountBlocks : " + Long.toString(countBlocks)
+ "\nspace : " …Run Code Online (Sandbox Code Playgroud)