1. 前言
记得刚来公司 4 个多月的时候,公司的一个产品问我:可以获取 Android cpu 的温度吗?我答道:如果别人可以,我们也可以获取到。其实,我那时确实不知道怎么获取,也没具体去看这个问题。等到最近确实需要这个功能时,实在是找了好多资料,才找到了方案。现在想想,那时回答的实在是很轻率啊。
2. 正文
2.1 两种可选方案
查询网上的文章,有两种方案:
1,通过读取温度传感器的值近似作为 cpu 的温度:这个方案在没有温度传感器的手机上行不通;再者,这也是近似的温度,并不是 cpu 真正的温度;
2,通过读取 cpu 内核信息获取温度:这个方法直接也准确,但是到底读取哪些信息呢?资料并不充分。
2.2 采取的方案
本文采取的是第二种方案。
经过查询资料,有更多的备选可以读取。可以查看下面的类:
public class CpuUtils {
private CpuUtils() {
//no instance
}
private static final List<String> CPU_TEMP_FILE_PATHS = Arrays.asList(
"/sys/devices/system/cpu/cpu0/cpufreq/cpu_temp",
"/sys/devices/system/cpu/cpu0/cpufreq/FakeShmoo_cpu_temp",
"/sys/class/thermal/thermal_zone0/temp",
"/sys/class/i2c-adapter/i2c-4/4-004c/temperature",
"/sys/devices/platform/tegra-i2c.3/i2c-4/4-004c/temperature",
"/sys/devices/platform/omap/omap_temp_sensor.0/temperature",
"/sys/devices/platform/tegra_tmon/temp1_input",
"/sys/kernel/debug/tegra_thermal/temp_tj",
"/sys/devices/platform/s5p-tmu/temperature",
"/sys/class/thermal/thermal_zone1/temp",
"/sys/class/hwmon/hwmon0/device/temp1_input",
"/sys/devices/virtual/thermal/thermal_zone1/temp",
"/sys/devices/virtual/thermal/thermal_zone0/temp",
"/sys/class/thermal/thermal_zone3/temp",
"/sys/class/thermal/thermal_zone4/temp",
"/sys/class/hwmon/hwmonX/temp1_input",
"/sys/devices/platform/s5p-tmu/curr_temp");
public static final Maybe<CpuTemperatureResult> getCpuTemperatureFinder() {
return Observable
.fromIterable(CPU_TEMP_FILE_PATHS)
.map(new Function<String, CpuTemperatureResult>() {
@Override
public CpuTemperatureResult apply(String path) {
Double temp = readOneLine(new File(path));
String validPath = "";
double currentTemp = 0.0D;
if (isTemperatureValid(temp)) {
validPath = path;
currentTemp = temp;
} else if (isTemperatureValid(temp / (double) 1000)) {
validPath = path;
currentTemp = temp / (double) 1000;
}
return new CpuTemperatureResult(validPath, (int) currentTemp);
}
}).filter(new Predicate<CpuTemperatureResult>() {
@Override
public boolean test(CpuTemperatureResult cpuTemperatureResult) throws Exception {
return !TextUtils.isEmpty(cpuTemperatureResult.getFilePath())
&& (cpuTemperatureResult.getTemp() != 0);
}
}).firstElement();
}
private static double readOneLine(File file) {
FileInputStream fileInputStream = null;
String s = "";
try {
fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
s = bufferedReader.readLine();
fileInputStream.close();
inputStreamReader.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
double result = 0;
try {
result = Double.parseDouble(s);
} catch (NumberFormatException ignored) {
}
return result;
}
private static boolean isTemperatureValid(double temp) {
return temp >= -30.0D && temp <= 250.0D;
}
}
上面的代码用到了 RxJava 的操作符来处理集合的遍历。思路就是遍历读取集合中的文件,获取到信息;判断符合条件,就作为 cpu 的温度;如果都不符合,那么就读取不到 cpu 的温度。
这个方案也不是兼容所有的手机的,但是确实兼容性比较高。
3. 最后
感谢这个开源项目:
https://github.com/kamgurgul/cpu-info
,提供了较为完备的解决方案。
参考
1,
Android获取手机Cpu温度
2,
https://github.com/kamgurgul/cpu-info
版权声明:本文为willway_wang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。