如何在运行Android 13的树莓派4上用Kotlin安卓应用获取CPU温度
解决LineageOS 20(Android 13)树莓派4获取CPU温度的问题
原代码的核心问题
- 路径缺失前缀:原命令里的
sys/class/thermal/thermal_zone0/temp少了开头的/,导致无法定位到正确的sysfs节点 - 未处理错误流:执行
Runtime.exec后只读取了输入流,未处理错误流会导致进程阻塞,无法正常完成执行 - 节点编号可能不符:树莓派4的CPU温度节点不一定是
thermal_zone0,存在因硬件配置或系统差异使用其他编号的可能 - 命令路径不明确:直接调用
cat可能因系统环境变量问题找不到可执行文件,需指定完整路径
排查前置步骤
- 确认正确的温度节点:
在ADB Shell中执行ls /sys/class/thermal/列出所有thermal节点,再逐个执行cat /sys/class/thermal/thermal_zoneX/temp,找到能返回有效数字(通常是五位数,比如45000代表45℃)的节点 - 验证应用访问权限:
执行adb shell run-as 你的应用包名 cat /sys/class/thermal/目标节点/temp,如果能正常输出温度值,说明应用具备读取权限;否则需要将应用设为系统应用或获取ROOT权限
修正后的实现方案
方案1:直接读取文件(更高效可靠)
fun cpuTemperature(): Float { return try { // 优先尝试常见节点,可根据排查结果调整 val possibleNodes = listOf( "/sys/class/thermal/thermal_zone0/temp", "/sys/class/thermal/thermal_zone1/temp" ) var tempValue: String? = null for (nodePath in possibleNodes) { val tempFile = File(nodePath) if (tempFile.exists()) { tempValue = tempFile.readText().trim() break } } tempValue?.takeIf { it.isNotEmpty() }?.toFloat()?.div(1000.0f) ?: 51.0f } catch (e: Exception) { e.printStackTrace() 0.0f } }
方案2:修复命令执行逻辑(适配权限场景)
fun cpuTemperature(): Float { return try { // 使用完整路径调用cat命令,指定正确的sysfs节点 val cmd = arrayOf("/system/bin/cat", "/sys/class/thermal/thermal_zone0/temp") val process = Runtime.getRuntime().exec(cmd) // 必须读取错误流,避免进程阻塞 val errorReader = BufferedReader(InputStreamReader(process.errorStream)) errorReader.readLines().forEach { println("读取温度错误:$it") } process.waitFor() val inputReader = BufferedReader(InputStreamReader(process.inputStream)) val tempLine = inputReader.readLine()?.trim() tempLine?.takeIf { it.isNotEmpty() }?.toFloat()?.div(1000.0f) ?: 51.0f } catch (e: Exception) { e.printStackTrace() 0.0f } }
额外注意事项
- 若应用无权限读取sysfs节点,可尝试将应用打包为系统应用,或获取ROOT权限后在命令前添加
/system/bin/su -c前缀 - LineageOS部分安全限制可能影响sysfs访问,可临时在开发者选项中关闭相关安全验证(不建议长期开启)
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

