完善cpu信息

This commit is contained in:
xsean 2025-12-23 15:27:44 +08:00
parent 985eba8516
commit 25b5d7b977
3 changed files with 706 additions and 28 deletions

View File

@ -1,5 +1,6 @@
package com.xyzshell.andinfo.libs package com.xyzshell.andinfo.libs
import android.os.Build
import com.xyzshell.andinfo.libs.cpu.models.Cache import com.xyzshell.andinfo.libs.cpu.models.Cache
import com.xyzshell.andinfo.libs.cpu.models.Cluster import com.xyzshell.andinfo.libs.cpu.models.Cluster
import com.xyzshell.andinfo.libs.cpu.models.Core import com.xyzshell.andinfo.libs.cpu.models.Core
@ -7,60 +8,640 @@ import com.xyzshell.andinfo.libs.cpu.models.Package
import com.xyzshell.andinfo.libs.cpu.models.Processor import com.xyzshell.andinfo.libs.cpu.models.Processor
import com.xyzshell.andinfo.libs.cpu.models.UarchInfo import com.xyzshell.andinfo.libs.cpu.models.UarchInfo
import com.xyzshell.andinfo.libs.cpu.utils.CpuInfoUtils import com.xyzshell.andinfo.libs.cpu.utils.CpuInfoUtils
import java.io.File
/**
* CPU 信息类
* 用于获取设备处理器的详细信息包括核心数频率架构缓存等
*/
class CpuInfo { class CpuInfo {
// ==================== 基础处理器信息 ====================
/**
* 获取所有逻辑处理器列表
* @return 逻辑处理器列表
*/
val processors: List<Processor> val processors: List<Processor>
get() = CpuInfoUtils.getProcessors() get() = CpuInfoUtils.getProcessors()
/**
* 获取所有物理核心列表
* @return 物理核心列表
*/
val cores: List<Core> val cores: List<Core>
get() = CpuInfoUtils.getCores() get() = CpuInfoUtils.getCores()
/**
* 获取所有核心集群列表大小核分组
* @return 集群列表
*/
val clusters: List<Cluster> val clusters: List<Cluster>
get() = CpuInfoUtils.getClusters() get() = CpuInfoUtils.getClusters()
/**
* 获取所有物理封装芯片列表
* @return 封装列表
*/
val packages: List<Package> val packages: List<Package>
get() = CpuInfoUtils.getPackages() get() = CpuInfoUtils.getPackages()
/**
* 获取所有微架构信息列表
* @return 微架构信息列表
*/
val uarchs: List<UarchInfo> val uarchs: List<UarchInfo>
get() = CpuInfoUtils.getUarchs() get() = CpuInfoUtils.getUarchs()
// ==================== 缓存信息 ====================
/**
* L1 指令缓存列表
* @return L1i 缓存列表
*/
val l1iCaches: List<Cache> val l1iCaches: List<Cache>
get() = CpuInfoUtils.getL1iCaches() get() = CpuInfoUtils.getL1iCaches()
/**
* L1 数据缓存列表
* @return L1d 缓存列表
*/
val l1dCaches: List<Cache> val l1dCaches: List<Cache>
get() = CpuInfoUtils.getL1dCaches() get() = CpuInfoUtils.getL1dCaches()
/**
* L2 缓存列表
* @return L2 缓存列表
*/
val l2Caches: List<Cache> val l2Caches: List<Cache>
get() = CpuInfoUtils.getL2Caches() get() = CpuInfoUtils.getL2Caches()
/**
* L3 缓存列表
* @return L3 缓存列表
*/
val l3Caches: List<Cache> val l3Caches: List<Cache>
get() = CpuInfoUtils.getL3Caches() get() = CpuInfoUtils.getL3Caches()
/**
* L4 缓存列表
* @return L4 缓存列表
*/
val l4Caches: List<Cache> val l4Caches: List<Cache>
get() = CpuInfoUtils.getL4Caches() get() = CpuInfoUtils.getL4Caches()
fun hardware(): String { // ==================== 处理器名称和供应商 ====================
return if (processors.isNotEmpty()) {
processors[0].cpuPackage?.name ?: "未知" /**
* 获取处理器名称SoC 型号
* @return 处理器名称例如 "Qualcomm Snapdragon 888"
*/
fun getProcessorName(): String {
return if (packages.isNotEmpty()) {
packages[0].name
} else { } else {
"未知" "未知"
} }
} }
/**
* 获取处理器供应商
* @return 供应商名称例如 "Qualcomm", "ARM", "Intel"
*/
fun getVendor(): String {
return if (cores.isNotEmpty()) {
cores[0].vendor.name
} else {
"未知"
}
}
// ==================== 核心数量信息 ====================
/**
* 获取物理核心总数
* @return 核心数量
*/
fun getCoreCount(): Int {
return cores.size
}
/**
* 获取逻辑处理器总数
* @return 逻辑处理器数量
*/
fun getProcessorCount(): Int {
return processors.size
}
// ==================== 大小核信息 ====================
/**
* 大小核信息数据类
* @property bigCoreCount 大核数量
* @property midCoreCount 中核数量
* @property littleCoreCount 小核数量
* @property bigCoreFreq 大核最高频率Hz
* @property midCoreFreq 中核最高频率Hz
* @property littleCoreFreq 小核最高频率Hz
*/
data class ClusterInfo(
val bigCoreCount: Int,
val midCoreCount: Int,
val littleCoreCount: Int,
val bigCoreFreq: ULong,
val midCoreFreq: ULong,
val littleCoreFreq: ULong
)
/**
* 获取大小核信息
* @return 大小核信息对象
*/
fun getClusterInfo(): ClusterInfo {
if (clusters.isEmpty()) {
return ClusterInfo(0, 0, 0, 0UL, 0UL, 0UL)
}
// 按频率排序集群
val sortedClusters = clusters.sortedByDescending { cluster ->
cores.filter { it.cluster.clusterId == cluster.clusterId }
.maxOfOrNull { it.frequency } ?: 0UL
}
return when (sortedClusters.size) {
1 -> ClusterInfo(
0, 0, sortedClusters[0].coreCount.toInt(),
0UL, 0UL,
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL
)
2 -> ClusterInfo(
sortedClusters[0].coreCount.toInt(),
0,
sortedClusters[1].coreCount.toInt(),
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL,
0UL,
cores.filter { it.cluster.clusterId == sortedClusters[1].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL
)
else -> ClusterInfo(
sortedClusters[0].coreCount.toInt(),
sortedClusters[1].coreCount.toInt(),
sortedClusters[2].coreCount.toInt(),
cores.filter { it.cluster.clusterId == sortedClusters[0].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL,
cores.filter { it.cluster.clusterId == sortedClusters[1].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL,
cores.filter { it.cluster.clusterId == sortedClusters[2].clusterId }
.maxOfOrNull { it.frequency } ?: 0UL
)
}
}
// ==================== 制程和架构 ====================
/**
* 制程信息数据类
* @property process 制程工艺例如 "4nm", "5nm", "7nm"
* @property foundry 代工厂例如 "台积电", "三星"
* @property node 详细制程节点例如 "TSMC N4P", "Samsung 4LPE"
*/
data class ProcessInfo(
val process: String,
val foundry: String,
val node: String = ""
)
/**
* 获取制程信息根据 SoC 型号查询
* @return 制程信息对象包含制程工艺和代工厂
*/
fun getProcessInfo(): ProcessInfo {
val processorName = getProcessorName().lowercase()
return when {
// 高通 Snapdragon 8 系列
"snapdragon 8 gen 3" in processorName || "sm8650" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4P")
"snapdragon 8 gen 2" in processorName || "sm8550" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"snapdragon 8 gen 1" in processorName || "sm8450" in processorName ->
ProcessInfo("4nm", "三星", "Samsung 4LPE")
"snapdragon 888+" in processorName || "sm8350-ab" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"snapdragon 888" in processorName || "sm8350" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"snapdragon 870" in processorName || "sm8250-ac" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7P")
"snapdragon 865+" in processorName || "sm8250-ab" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7P")
"snapdragon 865" in processorName || "sm8250" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7P")
// 高通 Snapdragon 7 系列
"snapdragon 7+ gen 2" in processorName || "sm7475" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"snapdragon 778g" in processorName || "sm7325" in processorName ->
ProcessInfo("6nm", "台积电", "TSMC N6")
// 高通 Snapdragon 6 系列
"snapdragon 695" in processorName || "sm6375" in processorName ->
ProcessInfo("6nm", "台积电", "TSMC N6")
// 联发科 Dimensity 9000 系列
"dimensity 9300" in processorName || "mt6989" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4P")
"dimensity 9200+" in processorName || "mt6985" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"dimensity 9200" in processorName || "mt6983" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"dimensity 9000+" in processorName || "mt6985" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"dimensity 9000" in processorName || "mt6983" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
// 联发科 Dimensity 8000 系列
"dimensity 8300" in processorName || "mt6897" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"dimensity 8200" in processorName || "mt6896" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"dimensity 8100" in processorName || "mt6895" in processorName ->
ProcessInfo("5nm", "台积电", "TSMC N5")
// 联发科 Dimensity 1000 系列
"dimensity 1200" in processorName || "mt6893" in processorName ->
ProcessInfo("6nm", "台积电", "TSMC N6")
"dimensity 1080" in processorName || "mt6877" in processorName ->
ProcessInfo("6nm", "台积电", "TSMC N6")
// 联发科 Helio 系列
"helio g99" in processorName || "mt6789" in processorName ->
ProcessInfo("6nm", "台积电", "TSMC N6")
// 三星 Exynos
"exynos 2400" in processorName || "s5e9945" in processorName ->
ProcessInfo("4nm", "三星", "Samsung 4LPP+")
"exynos 2200" in processorName || "s5e9925" in processorName ->
ProcessInfo("4nm", "三星", "Samsung 4LPE")
"exynos 2100" in processorName || "s5e9840" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"exynos 1080" in processorName || "s5e1080" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"exynos 1380" in processorName || "s5e8835" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"exynos 1280" in processorName || "s5e8825" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
// 谷歌 Tensor
"tensor g3" in processorName || "gs301" in processorName ->
ProcessInfo("4nm", "三星", "Samsung 4LPP+")
"tensor g2" in processorName || "gs201" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"tensor g1" in processorName || "gs101" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
"tensor" in processorName ->
ProcessInfo("5nm", "三星", "Samsung 5LPE")
// 华为麒麟
"kirin 9000" in processorName ->
ProcessInfo("5nm", "台积电", "TSMC N5")
"kirin 9000e" in processorName ->
ProcessInfo("5nm", "台积电", "TSMC N5")
"kirin 990" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7+")
"kirin 980" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7")
"kirin 810" in processorName ->
ProcessInfo("7nm", "台积电", "TSMC N7")
// 苹果 A 系列(参考)
"apple a17" in processorName ->
ProcessInfo("3nm", "台积电", "TSMC N3B")
"apple a16" in processorName ->
ProcessInfo("4nm", "台积电", "TSMC N4")
"apple a15" in processorName ->
ProcessInfo("5nm", "台积电", "TSMC N5P")
"apple a14" in processorName ->
ProcessInfo("5nm", "台积电", "TSMC N5")
// 默认情况
else -> ProcessInfo("未知", "未知", "")
}
}
/**
* 获取制程信息字符串格式兼容旧版本
* @return 制程信息例如 "5nm", "7nm"
*/
fun getProcess(): String {
return getProcessInfo().process
}
/**
* 获取代工厂信息
* @return 代工厂名称例如 "台积电", "三星"
*/
fun getFoundry(): String {
return getProcessInfo().foundry
}
/**
* 获取详细制程节点
* @return 制程节点例如 "TSMC N4P", "Samsung 5LPE"
*/
fun getProcessNode(): String {
return getProcessInfo().node.ifEmpty { getProcessInfo().process }
}
/**
* 获取 CPU 架构
* @return 架构名称例如 "Cortex-A78", "Cortex-X1"
*/
fun getArchitecture(): String {
return if (cores.isNotEmpty()) {
cores[0].uarch.name
} else {
"未知"
}
}
/**
* 获取所有核心的架构列表去重
* @return 架构列表
*/
fun getAllArchitectures(): List<String> {
return cores.map { it.uarch.name }.distinct()
}
// ==================== ABI 信息 ====================
/**
* 获取当前设备的主 ABI
* @return ABI 字符串例如 "arm64-v8a", "armeabi-v7a"
*/
fun getAbi(): String {
return Build.SUPPORTED_ABIS.firstOrNull() ?: "未知"
}
/**
* 获取所有支持的 ABI 列表
* @return ABI 列表
*/
fun getSupportedAbis(): List<String> {
return Build.SUPPORTED_ABIS.toList()
}
// ==================== 频率信息 ====================
/**
* 单个核心的频率信息
* @property coreId 核心 ID
* @property currentFreq 当前频率KHz
* @property minFreq 最小频率KHz
* @property maxFreq 最大频率KHz
* @property availableFreqs 可用频率列表KHz
*/
data class CoreFrequencyInfo(
val coreId: Int,
val currentFreq: Long,
val minFreq: Long,
val maxFreq: Long,
val availableFreqs: List<Long>
)
/**
* 获取所有核心的详细频率信息
* @return 核心频率信息列表
*/
fun getCoreFrequencies(): List<CoreFrequencyInfo> {
val result = mutableListOf<CoreFrequencyInfo>()
for (i in 0 until getCoreCount()) {
val currentFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/scaling_cur_freq")
val minFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/cpuinfo_min_freq")
val maxFreq = readFrequency("/sys/devices/system/cpu/cpu$i/cpufreq/cpuinfo_max_freq")
val availableFreqs = readAvailableFrequencies("/sys/devices/system/cpu/cpu$i/cpufreq/scaling_available_frequencies")
result.add(CoreFrequencyInfo(i, currentFreq, minFreq, maxFreq, availableFreqs))
}
return result
}
/**
* 读取频率值
* @param path 频率文件路径
* @return 频率值KHz失败返回 0
*/
private fun readFrequency(path: String): Long {
return try {
File(path).readText().trim().toLongOrNull() ?: 0L
} catch (e: Exception) {
0L
}
}
/**
* 读取可用频率列表
* @param path 可用频率文件路径
* @return 频率列表KHz
*/
private fun readAvailableFrequencies(path: String): List<Long> {
return try {
File(path).readText().trim()
.split("\\s+".toRegex())
.mapNotNull { it.toLongOrNull() }
} catch (e: Exception) {
emptyList()
}
}
// ==================== 调频器信息 ====================
/**
* 获取指定核心的调频器
* @param coreId 核心 ID
* @return 调频器名称例如 "schedutil", "interactive"
*/
fun getGovernor(coreId: Int): String {
return try {
File("/sys/devices/system/cpu/cpu$coreId/cpufreq/scaling_governor")
.readText().trim()
} catch (e: Exception) {
"未知"
}
}
/**
* 获取所有核心的调频器
* @return 调频器列表
*/
fun getAllGovernors(): List<String> {
return (0 until getCoreCount()).map { getGovernor(it) }
}
/**
* 获取可用的调频器列表
* @param coreId 核心 ID
* @return 可用调频器列表
*/
fun getAvailableGovernors(coreId: Int = 0): List<String> {
return try {
File("/sys/devices/system/cpu/cpu$coreId/cpufreq/scaling_available_governors")
.readText().trim()
.split("\\s+".toRegex())
} catch (e: Exception) {
emptyList()
}
}
// ==================== CPU 特性 ====================
/**
* 获取 CPU 特性列表 /proc/cpuinfo 读取 Features
* @return CPU 特性列表
*/
fun getCpuFeatures(): List<String> {
return try {
File("/proc/cpuinfo").readLines()
.find { it.startsWith("Features") }
?.substringAfter(":")
?.trim()
?.split("\\s+".toRegex()) ?: emptyList()
} catch (e: Exception) {
emptyList()
}
}
// ==================== /proc/cpuinfo 原始信息 ====================
/**
* 获取 /proc/cpuinfo 的完整内容
* @return /proc/cpuinfo 文件内容
*/
fun getProcCpuInfo(): String {
return try {
File("/proc/cpuinfo").readText()
} catch (e: Exception) {
"无法读取 /proc/cpuinfo"
}
}
/**
* 解析 /proc/cpuinfo 为键值对映射
* @return 解析后的映射表
*/
fun parseProcCpuInfo(): Map<String, String> {
val result = mutableMapOf<String, String>()
try {
File("/proc/cpuinfo").readLines().forEach { line ->
if (line.contains(":")) {
val parts = line.split(":", limit = 2)
if (parts.size == 2) {
result[parts[0].trim()] = parts[1].trim()
}
}
}
} catch (e: Exception) {
// 忽略错误
}
return result
}
// ==================== 兼容性方法 ====================
/**
* 获取硬件名称兼容旧版本
* @return 处理器名称
*/
@Deprecated("使用 getProcessorName() 替代", ReplaceWith("getProcessorName()"))
fun hardware(): String {
return getProcessorName()
}
/**
* 获取文本格式的 CPU 信息摘要
* @return 格式化的文本信息
*/
fun text(): String { fun text(): String {
val stringBuilder = StringBuilder() val sb = StringBuilder()
stringBuilder.append("处理器数量: ${processors.size}\n")
processors.forEachIndexed { index, processor -> // 基本信息
stringBuilder.append(" 处理器 ${index}: ${processor.cpuPackage?.name ?: "未知"}\n") sb.append("=== CPU 基本信息 ===\n")
stringBuilder.append(" 核心: ${processor.core?.coreId ?: "未知"}\n") sb.append("处理器名称: ${getProcessorName()}\n")
stringBuilder.append(" 集群: ${processor.cluster?.clusterId ?: "未知"}\n") sb.append("供应商: ${getVendor()}\n")
val processInfo = getProcessInfo()
sb.append("制程工艺: ${processInfo.process}\n")
sb.append("代工厂: ${processInfo.foundry}\n")
if (processInfo.node.isNotEmpty()) {
sb.append("制程节点: ${processInfo.node}\n")
} }
stringBuilder.append("核心数量: ${cores.size}\n") sb.append("物理核心数: ${getCoreCount()}\n")
cores.forEachIndexed { index, core -> sb.append("逻辑处理器数: ${getProcessorCount()}\n")
stringBuilder.append(" 核心 ${index}: ID=${core.coreId}, 频率=${core.frequency}Hz\n")
// 大小核信息
val clusterInfo = getClusterInfo()
sb.append("\n=== 大小核配置 ===\n")
if (clusterInfo.bigCoreCount > 0) {
sb.append("大核: ${clusterInfo.bigCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.bigCoreFreq)}\n")
}
if (clusterInfo.midCoreCount > 0) {
sb.append("中核: ${clusterInfo.midCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.midCoreFreq)}\n")
}
if (clusterInfo.littleCoreCount > 0) {
sb.append("小核: ${clusterInfo.littleCoreCount} 个, 最高频率: ${formatFrequency(clusterInfo.littleCoreFreq)}\n")
}
// 架构信息
sb.append("\n=== 架构信息 ===\n")
sb.append("架构: ${getAllArchitectures().joinToString(", ")}\n")
sb.append("ABI: ${getAbi()}\n")
sb.append("支持的 ABI: ${getSupportedAbis().joinToString(", ")}\n")
// 调频器
sb.append("\n=== 调频器 ===\n")
sb.append("当前调频器: ${getGovernor(0)}\n")
sb.append("可用调频器: ${getAvailableGovernors().joinToString(", ")}\n")
// 核心详细频率
sb.append("\n=== 核心频率信息 ===\n")
getCoreFrequencies().forEach { freq ->
sb.append("CPU${freq.coreId}: 当前=${formatFrequency(freq.currentFreq.toULong() * 1000UL)}, ")
sb.append("范围=${formatFrequency(freq.minFreq.toULong() * 1000UL)}-${formatFrequency(freq.maxFreq.toULong() * 1000UL)}\n")
}
// 缓存信息
sb.append("\n=== 缓存信息 ===\n")
sb.append("L1i 缓存: ${l1iCaches.size}\n")
sb.append("L1d 缓存: ${l1dCaches.size}\n")
sb.append("L2 缓存: ${l2Caches.size}\n")
sb.append("L3 缓存: ${l3Caches.size}\n")
// CPU 特性
val features = getCpuFeatures()
if (features.isNotEmpty()) {
sb.append("\n=== CPU 特性 ===\n")
sb.append(features.joinToString(" "))
sb.append("\n")
}
return sb.toString()
}
/**
* 格式化频率显示
* @param freqHz 频率Hz
* @return 格式化后的频率字符串
*/
private fun formatFrequency(freqHz: ULong): String {
return when {
freqHz >= 1_000_000_000UL -> String.format("%.2f GHz", freqHz.toDouble() / 1_000_000_000)
freqHz >= 1_000_000UL -> String.format("%.0f MHz", freqHz.toDouble() / 1_000_000)
freqHz >= 1_000UL -> String.format("%.0f KHz", freqHz.toDouble() / 1_000)
else -> "$freqHz Hz"
} }
// 可以根据需要添加更多详细信息
return stringBuilder.toString()
} }
companion object { companion object {

View File

@ -6,11 +6,20 @@ import android.os.Build
import android.view.Display import android.view.Display
import android.graphics.Point import android.graphics.Point
import android.util.DisplayMetrics import android.util.DisplayMetrics
import kotlin.math.sqrt
/**
* 显示信息类用于获取设备屏幕相关信息
*/
class DisplayInfo(private val context: Context) { class DisplayInfo(private val context: Context) {
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
/**
* 获取默认显示器信息
* @return 默认显示器信息对象如果获取失败返回 null
*/
fun getDefaultDisplayInfo(): DefaultDisplayInfo? { fun getDefaultDisplayInfo(): DefaultDisplayInfo? {
val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: return null val defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: return null
@ -22,13 +31,24 @@ class DisplayInfo(private val context: Context) {
val mode = defaultDisplay.mode val mode = defaultDisplay.mode
val refreshRate = mode.refreshRate val refreshRate = mode.refreshRate
// 计算 PPI (每英寸像素数)
val isHdr = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val ppi = calculatePPI(displayMetrics.widthPixels, displayMetrics.heightPixels, displayMetrics.densityDpi)
defaultDisplay.hdrCapabilities?.supportedHdrTypes?.isNotEmpty() ?: false // 获取支持的刷新率列表
val supportedRefreshRates = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
defaultDisplay.supportedModes.map { it.refreshRate }.distinct().sorted()
} else { } else {
false listOf(refreshRate)
} }
// 检查是否支持 HDR 及 HDR 类型
val hdrTypes = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
defaultDisplay.mode?.supportedHdrTypes?.map { getHdrTypeName(it) } ?: emptyList()
} else {
emptyList()
}
val isHdr = hdrTypes.isNotEmpty()
// 检查是否支持广色域
val isWideColorGamut = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val isWideColorGamut = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
defaultDisplay.isWideColorGamut defaultDisplay.isWideColorGamut
} else { } else {
@ -43,22 +63,81 @@ class DisplayInfo(private val context: Context) {
densityDpi = displayMetrics.densityDpi, densityDpi = displayMetrics.densityDpi,
xdpi = displayMetrics.xdpi, xdpi = displayMetrics.xdpi,
ydpi = displayMetrics.ydpi, ydpi = displayMetrics.ydpi,
ppi = ppi,
refreshRate = refreshRate, refreshRate = refreshRate,
supportedRefreshRates = supportedRefreshRates,
isHdr = isHdr, isHdr = isHdr,
hdrTypes,
isWideColorGamut = isWideColorGamut isWideColorGamut = isWideColorGamut
) )
} }
/**
* 获取 HDR 类型名称
* @param hdrType HDR 类型常量
* @return HDR 类型名称
*/
private fun getHdrTypeName(hdrType: Int): String {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
when (hdrType) {
Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION -> "Dolby Vision"
Display.HdrCapabilities.HDR_TYPE_HDR10 -> "HDR10"
Display.HdrCapabilities.HDR_TYPE_HLG -> "HLG"
Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS -> "HDR10+"
else -> "Unknown HDR Type ($hdrType)"
}
} else {
"Unknown"
}
}
/**
* 计算屏幕 PPI (每英寸像素数)
* @param widthPixels 屏幕宽度像素
* @param heightPixels 屏幕高度像素
* @param densityDpi 屏幕密度 DPI
* @return PPI
*/
private fun calculatePPI(widthPixels: Int, heightPixels: Int, densityDpi: Int): Double {
// 使用勾股定理计算对角线像素数
val diagonalPixels = sqrt((widthPixels * widthPixels + heightPixels * heightPixels).toDouble())
// 通过 densityDpi 计算屏幕对角线英寸数
// 160 DPI 是 Android 的基准密度 (mdpi)
val diagonalInches = diagonalPixels / densityDpi
// PPI = 对角线像素数 / 对角线英寸数
return diagonalPixels / diagonalInches
}
/**
* 默认显示器信息数据类
* @property id 显示器 ID
* @property name 显示器名称
* @property widthPixels 屏幕宽度像素
* @property heightPixels 屏幕高度像素
* @property densityDpi 屏幕密度 DPI
* @property xdpi X 轴每英寸像素数
* @property ydpi Y 轴每英寸像素数
* @property ppi 屏幕 PPI每英寸像素数
* @property refreshRate 当前刷新率Hz
* @property supportedRefreshRates 支持的刷新率列表Hz
* @property isHdr 是否支持 HDR
* @property hdrTypes 支持的 HDR 类型列表
* @property isWideColorGamut 是否支持广色域
*/
data class DefaultDisplayInfo( data class DefaultDisplayInfo(
val id: Int, val id: Int, // 显示器 ID
val name: String, val name: String, // 显示器名称
val widthPixels: Int, val widthPixels: Int, // 屏幕宽度(像素)
val heightPixels: Int, val heightPixels: Int, // 屏幕高度(像素)
val densityDpi: Int, val densityDpi: Int, // 屏幕密度 DPI
val xdpi: Float, val xdpi: Float, // X 轴 DPI
val ydpi: Float, val ydpi: Float, // Y 轴 DPI
val refreshRate: Float, val ppi: Double, // 屏幕 PPI
val isHdr: Boolean, val refreshRate: Float, // 当前刷新率Hz
val isWideColorGamut: Boolean val supportedRefreshRates: List<Float>, // 支持的刷新率列表Hz
val isHdr: Boolean, // 是否支持 HDR
val hdrTypes: List<String>, // 支持的 HDR 类型列表
val isWideColorGamut: Boolean // 是否支持广色域
) )
} }

View File

@ -1,14 +1,32 @@
package com.xyzshell.andinfo.utils package com.xyzshell.andinfo.utils
import android.util.Base64
import com.google.gson.Gson import com.google.gson.Gson
import okhttp3.* import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException import java.io.IOException
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
class WebService { class WebService {
private val client = OkHttpClient() private val client = OkHttpClient()
val gson = Gson() val gson = Gson()
// AES 密钥 (必须是 16/24/32 字节)
private val aesKey = "e67cbcee5e573d1b"
// AES 加密
fun encrypt(plainText: String): String {
return try {
val secretKey = SecretKeySpec(aesKey.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val encryptedBytes = cipher.doFinal(plainText.toByteArray())
Base64.encodeToString(encryptedBytes, Base64.NO_WRAP)
} catch (e: Exception) {
throw Exception("加密失败: ${e.message}")
}
}
fun postData(url: String, jsonData: String, callback: (String?, Exception?) -> Unit) { fun postData(url: String, jsonData: String, callback: (String?, Exception?) -> Unit) {
val mediaType = "application/json; charset=utf-8".toMediaType() val mediaType = "application/json; charset=utf-8".toMediaType()
val body = jsonData.toRequestBody(mediaType) val body = jsonData.toRequestBody(mediaType)