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廠商 | 對應的核心字首 |
---|---|
MTK | mtktscpu |
Qualcomm | tsens_tz_sensor |
Exynos(三星) | exynos |
不要問我怎麼來的,多使用ADB真機除錯,使用以上的命令你也可以總結出來這些東西。
ADB SHELL THERMAL.png通過for迴圈,遍歷thermal_zone
,cat type
出來的資訊判斷是否包含了以上兩種CPU的關鍵字,則可以判斷該目錄是否儲存了CPU核心資訊。
只要判斷了那些目錄是屬於核心資訊的,獲取溫度就手到拈來。只需要cat
另一個引數temp
那麼輸出的資訊就是我們需要的溫度啦。
奏是這麼簡單。
image.png還有一點需要注意的是,某些手機返回回來的引數(很多情況下是thermal_zone0)是精確到小數點後3位,但是沒有小數點,例如45300,其實是45.3℃。這裡需要轉換。
Android應用使用ADB命令,這個就不用再提了吧,使用FileInputStream
、InputStreamReader
、BufferedReader
來讀取應該大家都會。如果不會百度下也是很快就能搞定的。
對於沒有許可權的手機:
現在市面上有很多安全清理軟體都是有CPU溫度監控的模組,而他們獲取的溫度,可能是使用batteryTemp代替了CPU真正的溫度。而獲取電池溫度的方式,只需要使用電池廣播就行了。
最後程式碼就不貼了,原理就是這樣。希望能幫助到有需要的朋友。老是複製貼上哪有自己碼程式碼有意思是吧。