繁体   English   中英

如何在 Android Oreo API 26 及更高版本上检查设备是否具有低存储空间

[英]How to check if the device has Low Storage on Android Oreo API 26 and Above

如何检查设备在 Android 8 Oreo 上的存储空间是否不足。 我在 Android 文档中看到Intent.ACTION_DEVICE_STORAGE_LOW在 API 26 中已弃用。

此常量在 API 级别 26 中已弃用。如果您的应用程序以 O 或更高版本为目标,则此广播将不再传送到清单中定义的任何 BroadcastReceiver。 相反,强烈建议应用程序使用改进的 getCacheDir() 行为,以便系统可以在需要时自动释放存储空间。 - 安卓文档

他们鼓励我改用 getCacheDir()。

但我不太了解它,因为 getCacheDir() 似乎将系统缓存目录路径作为 FILE 对象返回,它只能用于清除缓存等。

但我需要检查设备是否在设备存储上运行不足。 我希望有人能在这方面帮助我

正如问题中正确陈述的那样,不建议使用API​​ 26 Intent.ACTION_DEVICE_STORAGE_LOW而是建议使用Context#getCacheDir()来释放应用程序缓存中的空间。

这有多个问题(下面列举),但首先:请注意,保持缓存“合理地小”(例如1 MB)是一个好习惯,我引用:

getCacheDir()

返回表示应用程序临时缓存文件的内部目录的文件。 确保在不再需要时删除每个文件,并对在任何给定时间使用的内存量(例如1MB)实施合理的大小限制。

警告:如果系统存储空间不足,则可能会在没有警告的情况下删除缓存文件。

(资源)

所以,这里有三个问题:

  1. 我们应该清除缓存,但它可能已经相当小(例如1 MB),因此清除它可能不会释放足够的空间以使空闲存储再次变得正常(类似于之前可以使用的已弃用的Intent.ACTION_DEVICE_STORAGE_OK为了这)
  2. 如上所述,系统已经清除了缓存,因为存储空间很小,如果系统决定,系统可能会清除应用程序的缓存。 因此,自己清除它可能不会释放任何存储空间。
  3. 该文档根本没有说明如何实际检测设备是否存储不足。

因此,清除缓存似乎没有帮助,因此我不会详细介绍如何执行此操作。

但是,根据这个答案 ,我们可以假设在10%的空闲存储空间下,系统进入我们想要检测的低存储状态。 根据链接的答案,这个数字是Android的默认值,但是几乎没有阻止设备制造商(或ROM开发者)更改它。

在这一点上,对我来说,这10%是一个神奇的数字,我想知道我是否可以通过编程方式确定这个阈值。 如果您知道如何,请编辑我的答案,自己发布答案或评论我的答案。

要使用getCacheDir()执行此操作,您可以使用以下命令:

Java,来自Context (例如Activity ):

File cacheDir = getCacheDir();
if (cacheDir.getUsableSpace() * 100 / cacheDir.getTotalSpace() <= 10) { // Alternatively, use cacheDir.getFreeSpace()
  // Handle storage low state
} else {
  // Handle storage ok state
}

Kotlin,来自一个Context (例如Activity ):

if (cacheDir.usableSpace * 100 / cacheDir.totalSpace <= 10) { // Alternatively, use cacheDir.freeSpace
  // Handle storage low state
} else {
  // Handle storage ok state
}

现在,无论是使用可用空间还是可用空间,这对我来说都不是很清楚。 这里描述不同之处。

潜入Android源代码,我发现了一个系统服务,我无法在我的代码中访问,检查低存储: DeviceStorageMonitorService 它从StorageManager#getStorageLowBytes获取其lowBytes变量,我也无法访问它。 如果以某种非hacky方式实现这一点,那将是获得低存储字节阈值的一种方法。 在那里你看到源使用了getUsableSpace() ,这就是为什么我为我的代码片段选择了而不是getFreeSpace()的原因。

在深入研究android excatlty 的代码后,释放名为DeviceStorageMonitorService 的Low storage 通知的类

这是我发现的,有些手机使用sys_storage_threshold_percentage ,有些手机使用sys_storage_threshold_max_bytes所以要测试存储,您应该从 Settings.Secure 中获取实际值,使用这两个键,然后比较sys_storage_threshold_percentage * Total memory size of data system foldersys_storage_threshold_max_bytes sys_storage_threshold_percentage * Total memory size of data system folder然后再sys_storage_threshold_max_bytes取较小的值并将其与数据系统文件夹的可用存储空间进行比较,这是如何执行的代码

 private void checkForLowStorage() { long mFreeMem = getDeviceCurrentStorage(); float deviceLowStorageThreshold = getDeviceLowStorageThreshold(); if (mFreeMem <= deviceLowStorageThreshold) { Toast.makeText(this, R.string.low_storage_error_message, Toast.LENGTH_LONG).show(); // Handle storage low state } else { // Handle storage ok state } } private long getDeviceCurrentStorage() { long mFreeMem = 0; try { StatFs mDataFileStats = new StatFs("/data"); mDataFileStats.restat("/data"); mFreeMem = (long) mDataFileStats.getAvailableBlocksLong() * mDataFileStats.getBlockSizeLong(); } catch (IllegalArgumentException e) { // use the old value of mFreeMem } return mFreeMem; } private long getDeviceLowStorageThreshold() { long value = Settings.Secure.getInt( getContentResolver(), "sys_storage_threshold_percentage", 10); StatFs mDataFileStats = new StatFs("/data"); long mTotalMemory = ((long) mDataFileStats.getBlockCountLong() * mDataFileStats.getBlockSizeLong()) / 100L; value *= mTotalMemory; long maxValue = Settings.Secure.getInt( getContentResolver(), "sys_storage_threshold_max_bytes", 500*1024*1024); return Math.min(value, maxValue); }

我仍在测试它,不知道它是否不适用于某些设备

由greenapps在评论中回答:

一旦getCacheDir()提供了使用存储的路径,您就可以使用该路径来确定该“分区”的大小和可用空间

getCacheDir()在内部存储中提供目录

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM