氣壓傳感器兩年前已經開始被手機制造商運用在其設備上,但貌似沒有引發開發者足夠的重視。像Galaxy S III 、Galaxy Note 2和小米2手機上都有,不過你們對於氣壓傳感器比較陌生。其實大氣壓無處不在,咱們能夠利用它來爲咱們完成諸如海拔高度測量甚至是空間定位的任務。android
先說些題外話,舒緩一下工做學習的疲憊。前些天跟朋友一塊兒去戶外活動,爬山到半山腰,忽然朋友問我,如今海拔大概多少?我腦子靈光一閃,前些天一個在小米工做的朋友在其小米2手機上打開指南針應用對我說如今海拔多少多少,而我如今手頭正有一臺小米4手機,趕忙拿出來打開指南針應用,結果氣壓是出來了,海拔計算卻須要聯網,真是讓人掃興。也正是這一點讓我萌生了本身來計算的想法。網絡
既然說作,那就作吧,反正應該不會太難。首先網上查詢相關資料,計算本身的海拔高度一般有兩種方法,一是經過GPS全球定位系統,二是經過測出大氣壓,而後根據氣壓值計算出海拔高度。框架
使用GPS全球定位系統獲取海拔簡單是簡單,只要獲取到Android系統提供LoctionManager服務,將提供者設置爲LocationManager.GPS_PROVIDER,在寫個GPS狀態監聽器GpsStatus.Listener,最後在實現一個LocationListener來實時監聽位置的變化,在onLocationChanged回調函數中取出location參數,裏面就包含了海拔高度值(getAltitude())。關鍵代碼以下ide
1 private LocationManager lm; 2 lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); 3 if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){ 4 Log.i(TAG, "請先開啓GPS"); 5 showAlertDialog(context, "開啓GPS,定位更準確;取消則使用網絡定位,粗略定位"); 6 } 7 if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){ 8 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 9 context.startActivity(intent); 10 } 11 lm.addGpsStatusListener(listener); 12 lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
其中listener和locationListener分別爲StatusListener和LocationListener的實例,使用起來也不難,主要代碼框架已經爲你生成了,只要查查android SDK的API就會明白的,就不說了。這種方式去測海拔,須要接收GPS信號。若是你在叢林或者洞穴或建築物內,極有多是接收不到GPS衛星信號的。這時候,能夠考慮使用壓力傳感器來測海拔高度。函數
先說說使用壓力傳感器來測海拔高度的原理,其實很是簡單,一些基本原理你必需要明白的:通常來講海拔越高,氣壓越低,他們之間存在某種關係,下文會講到的。有很多學者對海拔與氣壓作了研究,迴歸了很多海拔與氣壓的數據,他們的變化關係大概服從下面的表達式。學習
由於咱們要計算海拔(A),因此略做變化,能夠知道A的計算公式以下。spa
其中P爲當前的大氣壓,P0爲標準大氣壓。這樣,咱們只要獲取Android手機內置氣壓傳感器的值,就能夠初步估算出海拔高度了。實現起來也不難,關鍵代碼以下。翻譯
1 private SensorManager sensorManager = null; 2 sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); 3 mPressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); 4 if(mPressure == null) 5 { 6 mPressureVal.setText("您的手機不支持氣壓傳感器,沒法使用本軟件功能."); 7 return; 8 } 9 mAccelerate = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
而後在onResume()函數裏面註冊氣壓傳感器,在onPause()中註銷,這樣作固然是爲了節約用電嘛。code
sensorManager.registerListener(pressureListener, mPressure,
SensorManager.SENSOR_DELAY_NORMAL);
if(pressureListener!=null){ sensorManager.unregisterListener(pressureListener); }
還有一點必須獲取氣壓傳感器的值嘛,必需要有一個SensorEventListener對象(SensorManager註冊語句的pressureListener),代碼很簡單。orm
1 SensorEventListener pressureListener = new SensorEventListener() { 2 3 @Override 4 public void onSensorChanged(SensorEvent event) { 5 // TODO Auto-generated method stub 6 float sPV = event.values[0]; 7 mPressureVal.setText(String.valueOf(sPV)); 8 DecimalFormat df = new DecimalFormat("0.00"); 9 df.getRoundingMode(); 10 // 計算海拔 11 double height = 44330000*(1-(Math.pow((Double.parseDouble(df.format(sPV))/1013.25), 12 (float)1.0/5255.0))); 13 mAltitude.setText(df.format(height)); 14 } 15 16 @Override 17 public void onAccuracyChanged(Sensor sensor, int accuracy) { 18 // TODO Auto-generated method stub 19 20 } 21 };
海拔計算公式的實現天然也不是難事,基本上是翻譯一下就出來了。
其實海拔和睦壓的這種關係比較複雜,受多方面的因素影響,最爲顯著的是溫度的影響。大氣壓通俗來說是大氣對其餘物體的壓力,與空氣分子的密度和動能相關,因此同一海拔高度,溫度越高,氣壓越高。正是由於這個影響因素,使得氣壓測海拔有較明顯的偏差。若是是時隔不久,即溫度變化不大,測高度差仍是比較準確的,我作過實驗,利用氣壓能較爲準確的測出7層樓的高度,哈哈,是否是感受很靈敏呢?只是影響因素帶來的偏差還得想辦法消除。剛接觸Android不久,也沒寫過什麼博客,這個純屬扯扯,沒什麼技術難度,僅僅是爲了總結一下android開發的一些事兒,順便練練筆而已。