Android 獲取手機 cpu 溫度,你還不知道的超級方案

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章