存储信息修改
This commit is contained in:
parent
a43fcad558
commit
5239088041
@ -5,22 +5,27 @@ import android.os.Environment
|
||||
import android.os.StatFs
|
||||
import com.xyzshell.andinfo.libs.storage.models.EncryptionType
|
||||
import com.xyzshell.andinfo.utils.SystemProperties
|
||||
import java.io.File
|
||||
|
||||
class StorageInfo(private val context: Context) {
|
||||
|
||||
// 内部存储总空间
|
||||
val internalStorageTotalSpace: Long
|
||||
get() = StatFs(Environment.getDataDirectory().absolutePath).let { statFs ->
|
||||
statFs.blockCountLong * statFs.blockSizeLong
|
||||
}
|
||||
|
||||
// 内部存储可用空间
|
||||
val internalStorageAvailableSpace: Long
|
||||
get() = StatFs(Environment.getDataDirectory().absolutePath).let { statFs ->
|
||||
statFs.availableBlocksLong * statFs.blockSizeLong
|
||||
}
|
||||
|
||||
// 内部存储已使用空间
|
||||
val internalStorageUsedSpace: Long
|
||||
get() = internalStorageTotalSpace - internalStorageAvailableSpace
|
||||
|
||||
// 内部存储是否加密
|
||||
val isInternalStorageEncrypted: Boolean?
|
||||
get() = when (SystemProperties.getString("ro.crypto.state", "unknown")) {
|
||||
"encrypted" -> true
|
||||
@ -28,6 +33,7 @@ class StorageInfo(private val context: Context) {
|
||||
else -> null
|
||||
}
|
||||
|
||||
// 内部存储加密类型
|
||||
val internalStorageEncryptionType: EncryptionType?
|
||||
get() = when (SystemProperties.getString("ro.crypto.type", "unknown")) {
|
||||
"none" -> EncryptionType.NONE
|
||||
@ -36,6 +42,58 @@ class StorageInfo(private val context: Context) {
|
||||
else -> null
|
||||
}
|
||||
|
||||
// 内部存储文件系统类型
|
||||
val internalStorageFileSystemType: String?
|
||||
get() = try {
|
||||
// 方法1: 读取 /proc/mounts 文件
|
||||
File("/proc/mounts").readLines()
|
||||
.find { it.contains(" /data ") }
|
||||
?.split("\\s+".toRegex())
|
||||
?.getOrNull(2)
|
||||
?: run {
|
||||
// 方法2: 使用 StatFs (Android 8.0+)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
val statFs = StatFs("/data")
|
||||
statFs.javaClass.getMethod("getFileSystemName").invoke(statFs) as? String
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
// /data 目录总大小
|
||||
val dataDirectoryTotalSpace: Long
|
||||
get() = StatFs("/data").let { statFs ->
|
||||
statFs.blockCountLong * statFs.blockSizeLong
|
||||
}
|
||||
|
||||
// /data 目录已使用空间
|
||||
val dataDirectoryUsedSpace: Long
|
||||
get() = StatFs("/data").let { statFs ->
|
||||
val total = statFs.blockCountLong * statFs.blockSizeLong
|
||||
val available = statFs.availableBlocksLong * statFs.blockSizeLong
|
||||
total - available
|
||||
}
|
||||
|
||||
// 应用程序和数据占用大小
|
||||
val applicationsAndDataSize: Long
|
||||
get() = try {
|
||||
val dataDir = File("/data/data")
|
||||
val appDir = File("/data/app")
|
||||
calculateDirectorySize(dataDir) + calculateDirectorySize(appDir)
|
||||
} catch (e: Exception) {
|
||||
0L
|
||||
}
|
||||
|
||||
// 系统占用大小
|
||||
val systemSize: Long
|
||||
get() = StatFs(Environment.getRootDirectory().absolutePath).let { statFs ->
|
||||
statFs.blockCountLong * statFs.blockSizeLong
|
||||
}
|
||||
|
||||
// 外部存储总空间
|
||||
val externalStorageTotalSpace: Long?
|
||||
get() = runCatching {
|
||||
StatFs(Environment.getExternalStorageDirectory().absolutePath).let { statFs ->
|
||||
@ -43,6 +101,7 @@ class StorageInfo(private val context: Context) {
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
// 外部存储可用空间
|
||||
val externalStorageAvailableSpace: Long?
|
||||
get() = runCatching {
|
||||
StatFs(Environment.getExternalStorageDirectory().absolutePath).let { statFs ->
|
||||
@ -50,6 +109,7 @@ class StorageInfo(private val context: Context) {
|
||||
}
|
||||
}.getOrNull()
|
||||
|
||||
// 外部存储已使用空间
|
||||
val externalStorageUsedSpace: Long?
|
||||
get() = externalStorageTotalSpace?.let { total ->
|
||||
externalStorageAvailableSpace?.let { available ->
|
||||
@ -57,36 +117,76 @@ class StorageInfo(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// 外部存储是否为模拟存储
|
||||
val isExternalStorageEmulated: Boolean
|
||||
get() = Environment.isExternalStorageEmulated()
|
||||
|
||||
// 外部存储是否可移除
|
||||
val isExternalStorageRemovable: Boolean
|
||||
get() = Environment.isExternalStorageRemovable()
|
||||
|
||||
// 是否支持可更新的 APEX
|
||||
val hasUpdatableApex: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.apex.updatable")
|
||||
|
||||
// 是否使用 system-as-root 分区方案
|
||||
val usesSystemAsRoot: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.build.system_root_image")
|
||||
|
||||
// 是否使用 A/B 分区更新方案
|
||||
val usesAb: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.build.ab_update")
|
||||
|
||||
// A/B OTA 分区列表
|
||||
val abOtaPartitions: Array<String>?
|
||||
get() = SystemProperties.getString("ro.product.ab_ota_partitions")?.split(",")?.toTypedArray()
|
||||
|
||||
// 是否使用动态分区
|
||||
val usesDynamicPartitions: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.boot.dynamic_partitions")
|
||||
|
||||
// 是否使用改造的动态分区
|
||||
val usesRetrofittedDynamicPartitions: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.boot.dynamic_partitions_retrofit")
|
||||
|
||||
// 是否使用虚拟 A/B 分区
|
||||
val usesVirtualAb: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.virtual_ab.enabled")
|
||||
|
||||
// 是否使用改造的虚拟 A/B 分区
|
||||
val usesRetrofittedVirtualAb: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.virtual_ab.retrofit")
|
||||
|
||||
// 虚拟 A/B 分区是否启用压缩
|
||||
val usesCompressedVirtualAb: Boolean?
|
||||
get() = SystemProperties.getBoolean("ro.virtual_ab.compression.enabled")
|
||||
|
||||
// 计算目录大小(递归)
|
||||
private fun calculateDirectorySize(directory: File): Long {
|
||||
var size = 0L
|
||||
try {
|
||||
if (directory.exists() && directory.isDirectory) {
|
||||
directory.listFiles()?.forEach { file ->
|
||||
size += if (file.isDirectory) {
|
||||
calculateDirectorySize(file)
|
||||
} else {
|
||||
file.length()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// 可能因权限问题无法访问某些目录
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// 格式化存储大小
|
||||
fun formatBytes(bytes: Long): String {
|
||||
return when {
|
||||
bytes < 1024 -> "$bytes B"
|
||||
bytes < 1024 * 1024 -> String.format("%.2f KB", bytes / 1024.0)
|
||||
bytes < 1024 * 1024 * 1024 -> String.format("%.2f MB", bytes / (1024.0 * 1024))
|
||||
else -> String.format("%.2f GB", bytes / (1024.0 * 1024 * 1024))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user