1. 程式人生 > >Android獲取手機Cpu溫度

Android獲取手機Cpu溫度

在最近的專案中,需要獲取手機當前Cpu溫度,網上也有很多文章介紹,這裡記錄一下。

獲取CPU溫度的方式:

在Android系統中,獲取CPU溫度的方法並沒有直接提供給我們開發者,我們可以通過兩種方式來獲取Cpu溫度:

  • 1、 通過讀取手機感測器sensor的溫度近似於手機CPU溫度(當然這種方式只是一個近似的值,並不準確,同時還需要手機具備相應的感測器)
  • 2、 通過讀取CPU資訊來獲取(這種方式相較於前一種方式獲取到的資料準確很多,但是還是有一定的侷限性。)

通過兩種方式獲取溫度:

感測器(Sensor):

眾所周知,我們的Android手機有很多的感測器(陀螺儀,距離,溫度感測等),如果我們可以判斷手機上有我們需要的溫度感測器,我們就可以通過溫度感測器獲取到我們手機的大致溫度。而要想知道我們手機上是否具備我們所需的感測器,那我們就需要去遍歷一下我們手機裝置的感測器了。

  • 使用SensorManager,我們可以遍歷出裝置所有的感測器,名字,型別等。

    SensorManager mSmanager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    List<Sensor> allSensors = sm.getSensorList(Sensor.TYPE_ALL);
    

通過getSensorList方法我們就可以獲取到我們所有的感測器。獲取到所有感測器列表之後,我們怎樣判斷感測器的型別呢?

    for (Sensor s : allSensors) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
            typeName = SensorTypeName.getSensorTypeName(s.getType()) + " "
+ s.getStringType(); if (s.getStringType().toUpperCase().indexOf("TEMP") > 0) { // 可以看到,這裡將包含有TEMP關鍵字的sensor付給了變數mTempSensor // 而這個mTempSensor 就是我們需要的溫度感測器 mTempSensor = s; } } else { typeName = SensorTypeName.getSensorTypeName(s.getType()) + " "
+ s.getType(); } sb.append(String.format("\t型別:%s\n", typeName)); sb.append(String.format("\t裝置名稱:%s\n", s.getName())); sb.append(String.format("\t裝置版本:%s\n", s.getVersion())); sb.append(String.format("\t供應商:%s\n", s.getVendor())); sb.append("\n"); } // 這裡我們將所有的感測器都放在一個subStr中,方便檢視我們的結果 tx1.setText(sb.toString()); // 如果感測器不為空,那麼我們就可新增一個監聽,獲取感測器的溫度情況 if (mTempSensor != null) { sm.registerListener(mSensorEventListener, mTempSensor , SensorManager.SENSOR_DELAY_GAME); } // 溫度感測器的監聽器 private final SensorEventListener mSensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { if (event.sensor.getStringType().toUpperCase().indexOf("TEMP") > 0) { /*溫度感測器返回當前的溫度,單位是攝氏度(°C)。*/ float temperature = event.values[0]; Log.e("temperature: ", temperature); sm.unregisterListener(mSensorEventListener, mTempSensor); } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } };

到此,就是通過感測器獲取手機大致的溫度。
但是在實際的開發除錯過程中,很多手機是沒有溫度感測器的。那此時,就只有通過直接讀取Cpu資訊來獲取手機的CPU溫度了。

讀取CPU核心資訊獲取溫度:

讀取手機CPU資訊獲取溫度,我們需要獲取的是手機CPU核心(thermal)的資訊,而這個資訊是儲存在手機的/sys節點目錄中的。有開發經驗的朋友就知道,讀取手機快取中的檔案是需要有許可權的。而這個許可權是需要su許可權,也就是root許可權。那換而言之,一般的手機是讀取不到這個節點資訊的。這裡也是一個坑,需要注意。

讀取路徑:/sys/class/thermal/thermal_zone*
這裡的*對應了手機的核心資料夾編號,例如某些手機的*可能有17個(0~16),但是需要注意的是並不是所有的資料夾都是儲存CPU核心的資訊

那怎麼判斷哪個資料夾目錄使我們需要獲取的資訊目錄呢?

這裡介紹一個方式:
我們都知道,現在手機的處理器要不是高通(Qualcomm),要不是聯發科(MTK),當然還有其他的型別,但是市場主流是上邊的兩個。而這兩個CPU核心都有固定的名字。
我們可以通過cat命令讀取/sys/class/thermal/thermal_zone*/type獲取到的字串來判斷是哪種型別的CPU。也可以判斷該目錄是否是CPU核心資訊。

CPU廠商對應的核心字首
MTKmtktscpu
Qualcommtsens_tz_sensor
Exynos(三星)exynos

不要問我怎麼來的,多使用ADB真機除錯,使用以上的命令你也可以總結出來這些東西。

ADB SHELL THERMAL.png

通過for迴圈,遍歷thermal_zonecat type出來的資訊判斷是否包含了以上兩種CPU的關鍵字,則可以判斷該目錄是否儲存了CPU核心資訊。
只要判斷了那些目錄是屬於核心資訊的,獲取溫度就手到拈來。只需要cat另一個引數temp那麼輸出的資訊就是我們需要的溫度啦。

奏是這麼簡單。

image.png

還有一點需要注意的是,某些手機返回回來的引數(很多情況下是thermal_zone0)是精確到小數點後3位,但是沒有小數點,例如45300,其實是45.3℃。這裡需要轉換。

Android應用使用ADB命令,這個就不用再提了吧,使用FileInputStreamInputStreamReaderBufferedReader來讀取應該大家都會。如果不會百度下也是很快就能搞定的。

對於沒有許可權的手機:

現在市面上有很多安全清理軟體都是有CPU溫度監控的模組,而他們獲取的溫度,可能是使用batteryTemp代替了CPU真正的溫度。而獲取電池溫度的方式,只需要使用電池廣播就行了。

最後程式碼就不貼了,原理就是這樣。希望能幫助到有需要的朋友。老是複製貼上哪有自己碼程式碼有意思是吧。