在最近的項(xiàng)目中冯勉,需要獲取手機(jī)當(dāng)前Cpu溫度,網(wǎng)上也有很多文章介紹轴猎,這里記錄一下莉钙。
獲取CPU溫度的方式:
在Android系統(tǒng)中廓脆,獲取CPU溫度的方法并沒有直接提供給我們開發(fā)者,我們可以通過兩種方式來獲取Cpu溫度:
- 1磁玉、 通過讀取手機(jī)傳感器
sensor
的溫度近似于手機(jī)CPU溫度(當(dāng)然這種方式只是一個(gè)近似的值停忿,并不準(zhǔn)確,同時(shí)還需要手機(jī)具備相應(yīng)的傳感器) - 2蚊伞、 通過讀取CPU信息來獲取(這種方式相較于前一種方式獲取到的數(shù)據(jù)準(zhǔn)確很多席赂,但是還是有一定的局限性。)
通過兩種方式獲取溫度:
傳感器(Sensor):
眾所周知时迫,我們的Android手機(jī)有很多的傳感器(陀螺儀颅停,距離,溫度傳感等)掠拳,如果我們可以判斷手機(jī)上有我們需要的溫度傳感器癞揉,我們就可以通過溫度傳感器獲取到我們手機(jī)的大致溫度。而要想知道我們手機(jī)上是否具備我們所需的傳感器溺欧,那我們就需要去遍歷一下我們手機(jī)設(shè)備的傳感器了烧董。
-
使用SensorManager,我們可以遍歷出設(shè)備所有的傳感器胧奔,名字,類型等预吆。
SensorManager mSmanager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); List<Sensor> allSensors = sm.getSensorList(Sensor.TYPE_ALL);
通過getSensorList
方法我們就可以獲取到我們所有的傳感器龙填。獲取到所有傳感器列表之后,我們?cè)鯓优袛鄠鞲衅鞯念愋湍兀?/strong>
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關(guān)鍵字的sensor付給了變量mTempSensor
// 而這個(gè)mTempSensor 就是我們需要的溫度傳感器
mTempSensor = s;
}
} else {
typeName = SensorTypeName.getSensorTypeName(s.getType()) + " " + s.getType();
}
sb.append(String.format("\t類型:%s\n", typeName));
sb.append(String.format("\t設(shè)備名稱:%s\n", s.getName()));
sb.append(String.format("\t設(shè)備版本:%s\n", s.getVersion()));
sb.append(String.format("\t供應(yīng)商:%s\n", s.getVendor()));
sb.append("\n");
}
// 這里我們將所有的傳感器都放在一個(gè)subStr中岩遗,方便查看我們的結(jié)果
tx1.setText(sb.toString());
// 如果傳感器不為空,那么我們就可添加一個(gè)監(jiān)聽凤瘦,獲取傳感器的溫度情況
if (mTempSensor != null) {
sm.registerListener(mSensorEventListener, mTempSensor
, SensorManager.SENSOR_DELAY_GAME);
}
// 溫度傳感器的監(jiān)聽器
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) {
/*溫度傳感器返回當(dāng)前的溫度宿礁,單位是攝氏度(°C)。*/
float temperature = event.values[0];
Log.e("temperature: ", temperature);
sm.unregisterListener(mSensorEventListener, mTempSensor);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
到此蔬芥,就是通過傳感器獲取手機(jī)大致的溫度梆靖。
但是在實(shí)際的開發(fā)調(diào)試過程中控汉,很多手機(jī)是沒有溫度傳感器的。那此時(shí)返吻,就只有通過直接讀取Cpu信息來獲取手機(jī)的CPU溫度了姑子。
讀取CPU內(nèi)核信息獲取溫度:
讀取手機(jī)CPU信息獲取溫度,我們需要獲取的是手機(jī)CPU內(nèi)核(thermal)的信息测僵,而這個(gè)信息是存儲(chǔ)在手機(jī)的/sys
節(jié)點(diǎn)目錄中的街佑。有開發(fā)經(jīng)驗(yàn)的朋友就知道,讀取手機(jī)緩存中的文件是需要有權(quán)限的捍靠。而這個(gè)權(quán)限是需要su
權(quán)限沐旨,也就是root權(quán)限。那換而言之榨婆,一般的手機(jī)是讀取不到這個(gè)節(jié)點(diǎn)信息的磁携。這里也是一個(gè)坑,需要注意纲辽。
讀取路徑:
/sys/class/thermal/thermal_zone*
這里的*
對(duì)應(yīng)了手機(jī)的內(nèi)核文件夾編號(hào)颜武,例如某些手機(jī)的*
可能有17個(gè)(0~16),但是需要注意的是并不是所有的文件夾都是存儲(chǔ)CPU內(nèi)核的信息
那怎么判斷哪個(gè)文件夾目錄使我們需要獲取的信息目錄呢拖吼?
這里介紹一個(gè)方式:
我們都知道鳞上,現(xiàn)在手機(jī)的處理器要不是高通(Qualcomm),要不是聯(lián)發(fā)科(MTK)吊档,當(dāng)然還有其他的類型篙议,但是市場主流是上邊的兩個(gè)。而這兩個(gè)CPU內(nèi)核都有固定的名字怠硼。
我們可以通過cat
命令讀取/sys/class/thermal/thermal_zone*/type
獲取到的字符串來判斷是哪種類型的CPU鬼贱。也可以判斷該目錄是否是CPU內(nèi)核信息。
CPU廠商 | 對(duì)應(yīng)的內(nèi)核前綴 |
---|---|
MTK | mtktscpu |
Qualcomm | tsens_tz_sensor |
Exynos(三星) | exynos |
不要問我怎么來的香璃,多使用ADB真機(jī)調(diào)試这难,使用以上的命令你也可以總結(jié)出來這些東西。
通過for循環(huán)葡秒,遍歷thermal_zone
姻乓,cat type
出來的信息判斷是否包含了以上兩種CPU的關(guān)鍵字,則可以判斷該目錄是否保存了CPU內(nèi)核信息眯牧。
只要判斷了那些目錄是屬于內(nèi)核信息的蹋岩,獲取溫度就手到拈來。只需要cat
另一個(gè)參數(shù)temp
那么輸出的信息就是我們需要的溫度啦学少。
奏是這么簡單剪个。
還有一點(diǎn)需要注意的是,某些手機(jī)返回回來的參數(shù)(很多情況下是thermal_zone0)是精確到小數(shù)點(diǎn)后3位版确,但是沒有小數(shù)點(diǎn)扣囊,例如45300乎折,其實(shí)是45.3℃。這里需要轉(zhuǎn)換如暖。
Android應(yīng)用使用ADB命令笆檀,這個(gè)就不用再提了吧,使用FileInputStream
盒至、InputStreamReader
酗洒、BufferedReader
來讀取應(yīng)該大家都會(huì)。如果不會(huì)百度下也是很快就能搞定的枷遂。
對(duì)于沒有權(quán)限的手機(jī):
現(xiàn)在市面上有很多安全清理軟件都是有CPU溫度監(jiān)控的模塊樱衷,而他們獲取的溫度,可能是使用batteryTemp代替了CPU真正的溫度酒唉。而獲取電池溫度的方式矩桂,只需要使用電池廣播就行了。
最后代碼就不貼了痪伦,原理就是這樣侄榴。希望能幫助到有需要的朋友。老是復(fù)制粘貼哪有自己碼代碼有意思是吧网沾。