Android Developers:傳感器概述


大 多數Android設備有內置的傳感器,來測量運動,方向和各種環境條件。這些傳感器能提供高精度和准確度的原始數據,如果你想監控設備三維運動或者位 置,或者你想監控設備周圍的環境變化,是非常有用的。例如,游戲可能跟蹤設備重力傳感器的數據,來推斷復雜的用戶首飾和動作,例如傾斜,震動,旋轉,或者 振幅。同樣的,天氣應用可能使用設備的溫度傳感器和濕度傳感器的數據來計算和報告結露點,或者旅行應用可能使用磁場傳感器和加速度傳感器來報告一個指南針 方位。 

 

Android平台支持三大類的傳感器: 

  • 位移傳感器 

這些傳感器測量沿三個軸線測量加速度和旋轉。這類包含家加速度,重力傳感器,陀螺儀,和矢量傳感器。 

  • 環境傳感器 

這些傳感器測量各種環境參數,例如周圍的空氣溫度和壓力,光線,和濕度。這類包含氣壓,光線,和溫度傳感器。 

  • 位置傳感器 

這些傳感器測量設備的物理位置。這類包含方向和磁力傳感器。 

 

你能訪問設備上可用的傳感器,並通過使用Android傳感器框架獲取原始傳感器數據。傳感器框架提供了一些類和接口,來幫助你執行各種傳感器相關的任務。例如,你能使用傳感器框架做如下事情: 

  • 確定什么傳感器在設備上有效。 

  • 確定當個傳感器的功能,例如它的最大射程,廠商,電力需求,和分辨率。 

  • 獲取原始數據,並定義你獲取傳感器數據的最小速率。 

  • 注冊和注銷傳感器事件監聽,來監聽傳感器改變。 

 

這個主題提供了在Android平台上的傳感器的概覽。它也介紹了傳感器框架。 

 

傳感器介紹 

——————————————————————————————————————————————————————————— 

Android 傳感器框架讓你訪問許多類型的傳感器。這些傳感器的一些事基於硬件的,一些是基於軟件的。基於硬件的傳感器是內嵌到手機或者平板中的物理元件,它們通過直 接測量指定的環境屬性來得到它們的數據,例如加速度,磁場強度,或者角度變化。基於軟件的傳感器不是物理設備,盡管它們模仿基於硬件的傳感器。基於軟件的 傳感器從一個或更多基於硬件的傳感器獲取它們的數據,並且有時候被稱為虛擬傳感器或者合成傳感器。線性加速度傳感器和重力傳感器是基於軟件傳感器的例子。 表1總結了Android平台支持的傳感器。 

 

很少Android設備有所有類型的傳感器。例如,大部分手機和平板有一個加速計和磁場計,但是很少的設備擁有氣壓或者溫度傳感器。並且,一個設備可以擁有一個類型不止一個的傳感器。例如,設備能有兩個重力傳感器,每個有不同的范圍。 

 

表1.Android平台支持的傳感器類型 

傳感器 

類型 

描述 

常見用法 

TYPE_ACCELEROMETER 

硬件 

以m/s2測量它設備所有三個物理軸線方向(x,y,和z)加速度,包括重力。 

運動檢測(震動,傾角等)。 

TYPE_AMBIENT_TEMPERATURE 

硬件 

以攝氏度測量周圍空間的溫度,參閱下面的注釋。 

檢測空氣溫度。 

TYPE_GRAVITY 

軟件或硬件 

以m/s2測量重力, 

運動檢測(震動,傾角等)。 

TYPE_GYROSCOPE 

硬件 

以rad/s測量設備三個物理軸線方向(x,y,和z)。旋轉速度。 

旋轉檢測(旋轉,轉動等)。 

TYPE_LIGHT 

硬件 

以lx測量周圍的光線級別。 

控制屏幕的亮度。 

TYPE_LINEAR_ACCELERATION 

軟件或硬件 

以m/s2測量設備所有的三個物理軸線方向(x,y,和z)的加速度,包含包含重力。 

檢測沿着一個軸向的加速度。 

TYPE_MAGNETIC_FIELD 

硬件 

以uT測量周圍的三個物理軸線方向的磁場。 

創建一個羅盤。 

TYPE_ORIENTATION 

軟件 

測量設備所有三個物理軸線方向(x,y和x)的旋轉角度。當使用Level 3的API的時候,你能通過使用重力傳感器和磁場傳感器,結合getRotatinMatrix()方法,獲取設備的傾斜矩陣和旋轉矩陣。 

檢測設備的位置。 

TYPE_PRESSURE 

硬件 

以hPa和mbar測量周圍空氣氣壓。 

檢測空氣氣壓的改變。 

TYPE_PROXIMITY 

硬件 

 

手機在通話時的位置。 

TYPE_RELATIVE_HUMIDITY 

硬件 

一個百分比測量周圍相對濕度。 

檢測結露點,絕對,和相對濕度。 

TYPE_ROTATION_VECTOR 

軟件或硬件 

通過提供設備的三個旋轉矢量測量設備方向。 

檢測運動和檢測旋轉。 

TYPE_TEMPERATURE 

硬件 

以攝氏度測量設備的溫度。這個傳感器在不同設備實現不同,並且這個傳感器在API Level 14使用TYPE_AMBIENT_TEMPERATURE替代。 

檢測溫度。 

傳感器框架 

你能訪問這些傳感器,並通過使用Android傳感器框架獲取原始數據。Android傳感器框架式android.hardware包的一部分,包含下面的類和接口: 

SensorManager 

你能使用這個類來創建一個傳感器服務的實例。這個類提供了各種方法類訪問和列舉傳感器,注冊和注銷傳感器事件監聽,並獲取相應的信息。這個類也提供了幾個傳感器的常量,用戶報告傳感器的精確度,設置數據獲取速率,和校准傳感器。 

Sensor 

你能使用這個類類創建一個指定傳感器的實例。這個類提供了各種方法讓你確定傳感器的功能。 

SensorEvent 

系統使用這個類來創建一個傳感器對象,它提供了關於傳感器事件的信息。一個傳感器事件包含一下信息:原始傳感器數據,這類傳感器產生的事件,數據的准確性,和事件的時間戳。 

SensorEventListener 

你能使用這個接口來創建兩個回掉方法,當傳感器的值改變或者當傳感器的精度改變的時候,它接受通知(傳感器事件)。 

 

在一個典型的應用程序中,你使用這些傳感器相關的API來執行兩個基本任務: 

  • 識別傳感器和傳感器的性能 

如 果你的應用程序有功能依賴指定的類型的傳感器和功能,在運行時識別傳感器和傳感器的功能是非常有用的。例如,你可能想識別設備上可用的所有傳感器,和禁用 所有依賴不存在的傳感器的應用程序功能。同樣,你可能想識別一個指定類型的所有傳感器,所以你能選擇這個傳感器來為你的應用程序實現最佳性能。 

 

  • 檢測傳感器事件 

檢測傳感器事件是你如何獲取原始傳感器數據。傳感器事件每次發生的時候,傳感器檢測到它測量的參數的改變。傳感器事件給你提供了四個方面的信息:觸發這個事件的傳感器的名稱,事件的時間戳,事件的精准度,和觸發事件的原始傳感器數據。 

 

傳感器的可用性 

由於傳感器可用性設備和設備之間不同,不同的Android版本也不同。這是因為Android的傳感器在過去的幾個版本都被介紹了。例如,一些傳感器在Android1.5(API Level 3)中被介紹,但是一些直到Android2.3(API Level 9)也沒有被實現可用。同樣的,多個傳感器在Android2.3(API Level 9)和Anroid4.0(API Level 14)被介紹。兩個傳感器被棄用,並且被新的,更好的替代。 

 

表2概括了每個傳感器逐個平台分析的可用性。僅僅四個平台被列出是因為這些平台包含傳感器的變化。被列出的傳感器被棄用仍可在后續的平台可用(提供的傳感器在設備上存在),這符合Android向前兼容的策略。 

 

表2.傳感器平台的可用性 

傳感器 

Android4.0(API Level 14) 

Android2.3(API Level9) 

Android2.2(API Level 8) 

Android1.5(API Level 3) 

TYPE_ACCELEROMETER 

Yes 

Yes 

Yes 

Yes 

TYPE_AMBIENT_TEMPERATURE 

Yes 

n/a 

n/a 

n/a 

TYPE_GRAVITY 

Yes 

Yes 

n/a 

n/a 

TYPE_GYROSCOPE 

Yes 

Yes 

n/a1 

n/a1 

TYPE_LIGHT 

Yes 

Yes 

Yes 

Yes 

TYPE_LINEAR_ACCELERATION 

Yes 

Yes  

n/a 

n/a 

TYPE_MAGNETIC_FIELD 

Yes 

Yes 

Yes 

Yes 

TYPE_ORIENTATION 

Yes2 

Yes2 

Yes2 

Yes 

TYPE_PRESSURE 

Yes 

Yes 

n/a1 

n/a1 

TYPE_PROXIMITY 

Yes 

Yes 

Yes 

Yes 

TYPE_RELATIVE_HUMIDITY 

Yes 

n/a 

n/a 

n/a 

TYPE_ROTATION_VECTOR 

Yes 

Yes 

n/a 

n/a 

TYPE_TEMPERATURE 

Yes2 

Yes 

Yes 

Yes 

1這個類型的傳感器在Android1.5(API Level 3)被添加,但是直到Android2.3(API Level 9)也不可用。 

2這個傳感器是可用的,但是它被棄用。 

 

識別傳感器和傳感器的性能 

——————————————————————————————————————————————————————————— 

Android傳感器框架提供了許多方法,它使你的運行時確定設備上有哪些傳感器變得更容易。這個API也提供了方法,讓你確定傳感器的性能,例如它的大小范圍,它的分辨率,和它要求的電力。 

 

為了識別在設備上的傳感器,你首先需要獲取傳感器服務的索引。為此,你通過調用getSystemService()方法並傳遞SENSOR_SERVICE參數,創建SensorManager類的一個實例。例如: 

[java] view plain copy
  1. private SensorManager mSensorManager;   
  2. ...   
  3. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
下一步,你能通過調用getSensorList()方法,並使用TYPE_ALL常量獲取設備上所有傳感器列表。例如: 

[java] view plain copy
  1. List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);   
如果你想列出一個指定類型的所有傳感器,你應該使用其它的常量替代TYPE_ALL,例如TYPE_GYROSCOPE,TYPE_LINEAR_ACCELERATION,或者TYPE_GRAVITY。 

 

你 也可以通過調用getDefaultSensor()方法並傳遞指定傳感器的類型常量,來確定在設備上一個指定類型的傳感器是否存在。如果設備上有超過一 個指定類型的傳感器,一個傳感器必須被指定為默認的傳感器。如果一個指定類型的傳感器默認不存在,這個方法返回null,這意味着設備沒有這個類型的傳感 器。例如,下面的代碼用來檢測在設備上是否有一個磁場計: 

[java] view plain copy
  1. private SensorManager mSensorManager;   
  2. ...   
  3. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
  4. if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){   
  5.   // Success! There's a magnetometer.   
  6.   }   
  7. else {   
  8.   // Failure! No magnetometer.   
  9.   }   
注意: Android沒有要求設備制造商向它們的Android設備內嵌所有類型的傳感器,所以設備會有一個廣泛的傳感器配置。 

 

除 了列出設備上的傳感器之外,你能使用Sensor類的公共方法來檢測個傳感器的性能和屬性。如果你想你的應用程序,基於設備上可用的不同的傳感器或者不同 的傳感器性能,有不同的行為,這是非常有用的。例如,你可以使用getResolution()和getMaximumRange()方法類獲取傳感器的 測量的分辨率和大小范圍。你也能使用getPower()方法類獲取傳感器的電力需求。 

 

如 果你想針對不同廠商的傳感器或者不同版本的傳感器,優化你的應用程序,這兩個公共方法非常有用。例如,如果你的應用程序需要檢測用戶的手勢,例如震動和傾 斜,你應該創建一個數據過濾規則集合,針對最新的有指定廠商的重力傳感器的設備優化,和其它的數據過濾規則和針對沒有重力傳感器和僅有一個加速度計的設備 優化。下面的代碼例子向你展示了你如何能使用getVendor()和getVersion()方法來實現它。在這個例子中,我們查找一個Google Inc為廠商和3版本的重力傳感器。如果指定的傳感器在設備上不存在,我們嘗試使用加速度計。 

[java] view plain copy
  1. private SensorManager mSensorManager;   
  2. private Sensor mSensor;   
  3.    
  4. ...   
  5.    
  6. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
  7.    
  8. if (mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){   
  9.   List<Sensor> gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY);   
  10.   for(int i=0; i<gravSensors.size(); i++) {   
  11.     if ((gravSensors.get(i).getVendor().contains("Google Inc.")) &&   
  12.        (gravSensors.get(i).getVersion() == 3)){   
  13.       // Use the version 3 gravity sensor.   
  14.       mSensor = gravSensors.get(i);   
  15.     }   
  16.   }   
  17. }   
  18. else{   
  19.   // Use the accelerometer.   
  20.   if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){   
  21.     mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);   
  22.   }   
  23.   else{   
  24.     // Sorry, there are no accelerometers on your device.   
  25.     // You can't play this game.   
  26.   }   
  27. }   
另一個有用的方法是getMinDelay()方法,它返回傳感器用來檢測數據的最小時間戳(以微妙)。任何getMinDelay()方法返回非零數值的傳感器是一個流式傳感器。流式傳感器定期檢測數據,並在Andriod2.3(API Level 9)中被介紹。如果當你調用getMinDelay()方法時傳感器返回0,它意味着傳感器不是一個流式傳感器,因為它僅僅當感應的參數改變的時候報告數據。 

 

getMinDelay()方法是非常有用的,因為它讓你確定了傳感器獲取數據最小速率。如果在你應用程序中的某一個功能需要高數據獲取率或者一個流式傳感器,你能使用這個方法類確定是否這個傳感器滿足這些要求,然后相應的啟動或禁止你的應用程序的相關功能。 

 

當心:傳感器的最大數據獲取率並不一定是這個傳感器框架給你的應用程序發送傳感器數據的速率。傳感器框架通過傳感器事件報告數據,並且多個因素影響你的應用程序獲取傳感器事件的速率。更多信息查閱Monitoring Sensor Events。 

 

監測傳感器事件 

————————————————————————————————————————————————————————————— 

為了監測原始數據你需要實現兩個通過SensorEventListener接口定義的回掉方法: 

  • 傳感器精度的變化 

在 這種情況下系統調用onAccuracyChanged()方法,向你提供改變了新的傳感器精度的Sensor對象引用。精度通過四個狀態常量代 表:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH, 或者SENSOR_STATUS_UNRELIABLE。 

 

  • 傳感器報告一個新的值 

在這種情況下系統調用onSensorChanged()方法,向你提供了一個SensorEvent對象,一個SensorEvent對象包含關於新的傳感器數據的信息,包括:數據的精度,傳感器產生的數據,數據產生的時間戳,和傳感器記錄的新的數據。 

 

下面的代碼展示了如何使用onSensorChanged()方法來從一個光線傳感器監測數據。這個例子在一個在main.xml文件中以sensor_data被定義的TextView中,顯示了原始的數據。 

[java] view plain copy
  1. public class SensorActivity extends Activity implements SensorEventListener {   
  2.   private SensorManager mSensorManager;   
  3.   private Sensor mLight;   
  4.    
  5.   @Override   
  6.   public final void onCreate(Bundle savedInstanceState) {   
  7.     super.onCreate(savedInstanceState);   
  8.     setContentView(R.layout.main);   
  9.    
  10.     mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
  11.     mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);   
  12.   }   
  13.    
  14.   @Override   
  15.   public final void onAccuracyChanged(Sensor sensor, int accuracy) {   
  16.     // Do something here if sensor accuracy changes.   
  17.   }   
  18.    
  19.   @Override   
  20.   public final void onSensorChanged(SensorEvent event) {   
  21.     // The light sensor returns a single value.   
  22.     // Many sensors return 3 values, one for each axis.   
  23.     float lux = event.values[0];   
  24.     // Do something with this sensor value.   
  25.   }   
  26.    
  27.   @Override   
  28.   protected void onResume() {   
  29.     super.onResume();   
  30.     mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);   
  31.   }   
  32.    
  33.   @Override   
  34.   protected void onPause() {   
  35.     super.onPause();   
  36.     mSensorManager.unregisterListener(this);   
  37.   }   
  38. }   
在 這個例子中,當registerListener()方法被調用的時候,默認的數據延遲(SENSOR_DELAY_NORMAL)被指定。數據延遲(或 者取樣率)控制着通過onSensorChanged()回調方法向你的應用程序發送傳感器事件的間隔。默認的數據延遲使用2000000微秒,適合檢測 標准的屏幕方向變化。你能指定其它的數據延遲,例如SENSOR_DELAY_GAME(20000微秒延 遲),SENSOR_DELAY_UI(60000微秒延遲),或者SENSOR_DELAY_FASTEST(0微秒延遲)。在 Android3.0(API Level 11)中你也能指定以一個絕對的數值(以微秒)指定延遲。 

 

你 指定的延遲僅僅是一個建議延遲。Android系統和其它應用系統可以改變這個延遲。最好的方法,你應該指定你可以指定的最大延遲,因為系統通常會使用一 個比你指定的小的延遲(即,你應該選擇最慢的采樣率,但是仍然滿足你的應用程序的需求)。使用更大的延遲在處理器上強加更小的負載,因此耗能更低。 

 

沒有公共的方法來測定傳感器框架向你的應用程序發送傳感器事件的速率;然而,你可以使用時間戳,它和每個傳感器事件在幾個事件的基礎上計算采樣速率相關。一旦你設置了它,你不能改變采樣速率(延遲)。如果由於一些原因,你必須改變延遲,你將不得不注銷和注冊傳感器監聽器。 

 

同 樣重要的是要注意這個例子使用onResume()和onPause()回調方法來注冊和注銷傳感器事件監聽器。最為一項最好方法,你應該總是在你不需要 的時候禁用傳感器,尤其是當你的Activity被Pause的時候。沒有這樣做可能在短短幾個小時之內耗盡電池,因為一些傳感器有很大的功率要求,並且 會很快用完電池。當屏幕關閉的時候系統將會自動禁用傳感器。 

 

處理不同的傳感器配置 

————————————————————————————————————————————— 

Android沒有為設備指定一個標准的傳感器配置,這意味着設備廠商可以將任何它們想要的傳感器配置安裝到他們的的Android設備。造成一個結果,設備包含了在大范圍配置的各種傳感器。例如,Motorola Xoom有一個壓力傳感器,但是Samsung Nexus S沒有。同樣,Xoom和Nexus S有陀螺儀,但是HTC Nexus One沒有。如果你的應用程序依賴於一個指定類型的傳感器看,你必須確保這個傳感器在設備上存在,以至於你的應用程序能成功運行。你有兩個選擇來確保一個給定的傳感器在設備上存在: 

  • 在運行時檢測傳感器,並酌情啟動或禁用應用程序的功能 

  • 使用Google Play過濾器來規定制定傳感器配置的設備 

 

每個選擇都在下面的章節被討論 

 

在運行時檢測傳感器 

如 果你的應用程序使用一個指定的傳感器,但是不依賴它,你能使用傳感器框架在運行時檢測傳感器,然后酌情禁用和啟動應用程序功能。例如,一個導航引用程序可 能使用溫度傳感器,壓力傳感器,GPS傳感器,和磁場傳感器來顯示溫度,氣壓,位置和羅盤方位。如果設備沒有一個壓力傳感器,你能使用傳感器框架在運行時 檢測壓力傳感器的存在,然后你的應用程序顯示壓力的UI的部分。例如,下面的代碼檢查設備上是否有一個壓力傳感器: 

[java] view plain copy
  1. private SensorManager mSensorManager;   
  2.   ...   
  3.   mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
  4.   if (mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){   
  5.   // Success! There's a pressure sensor.   
  6.   }   
  7.   else {   
  8.   // Failure! No pressure sensor.   
  9.   }   
  10.    
使用Google Play過濾器來指定特定的傳感器配置 

如果你在Google Play中發布你的應用程序,你能在你的清單文件中使用<uses-feature>元素來過濾沒有你的應用程序相應的傳感器配置的設備。<uses-feature>元素有多個硬件描述符,讓你基於是否存在指定的傳感器來過濾應用程序。你能列舉的傳感器包括:加速度,氣壓,羅盤(磁場),陀螺儀,光線,和趨近。下面是一個示例清單實例,來過濾沒有加速度傳感器的應用程序 

[html] view plain copy
  1. <uses-feature android:name="android.hardware.sensor.accelerometer"   
  2.               android:required="true" />   
如果你向你的清單文件中添加這個元素和描述符,僅僅他們的設備有加速度傳感器的用戶能在Google Play中看見你的應用程序 

 

僅僅當你的應用程序徹底依賴一個特定的傳感器的時候,你應該設置這個描述符為android:required="true"。如果你的應用程序的一些功能使用一個傳感器,但是沒有傳感器仍然可以運行,你應該在<uses-feature>元素中列出這個傳感器,但是設置這個描述符為android:required="false"。 這個幫助確保設備能安裝你的應用,即使它們沒有這個特定的傳感器。這也是一個項目管理的最佳實踐,幫組你跟蹤你的應用程序使用的特性。記住,如果你的應用 程序使用一個特定的傳感器,但是沒有它仍然可以運行,那么你應該在運行時檢測這個傳感器,並且酌情啟動或禁用應用程序的功能。 

 

傳感器坐標系 

——————————————————————————————————————————————— 

通 常,傳感器框架使用一個標准的3維坐標系來表達數據值。對於大多數傳感器,當設備放置默認的方向(看圖1)的時候,坐標系被定義和設備的屏幕相關。當設備 放置為它默認的方向,X軸是水平並指向右邊,Y軸是豎直並指向上方,並且Z軸指向屏幕面的外側。在這個系統,坐標系統有負的Z值。這個坐標系被用於下面的 傳感器: 

  • 加速度傳感器 

  • 重力傳感器 

  • 陀螺儀傳感器 

  • 線性加速度傳感器 

  • 磁場傳感器 


圖1.傳感器API使用的坐標系系統(相對於一個設備) 

 

理解這個坐標表系的最重要的一點是,當設備屏幕的方向改變的時候,軸不改變—就是說,傳感器的坐標系當設備移動的時候從來都不會改變。這個和OpenGL坐標系是相同的。 

 

理解的另一點是你的應用程序不能假定設備的自然(默認)方向是豎屏。對於許多平板設備的自然方向是橫屏。並且傳感器的坐標系總是急於設備的自然方向。 

 

最終,如果你的應用程序匹配傳感器數據到屏幕顯示,你需要使用getRotation()方法來確定屏幕的旋轉,然后使用remapCoordinateSystem()方法來映射傳感器坐標系到屏幕坐標系。即使你的清單文件指定了僅僅豎屏幕顯示你也需要這樣做。 

 

更多關於傳感器坐標系的信息,包含如何處理屏幕旋轉的信息,查閱One Screen Turn Deserves Another。 

 

注意:一 些傳感器和方法使用的坐標系是相對於真實世界的參照(相對於設備的參考框架)。這些傳感器和方法返回數據代表設備的運動或者設備相對於地球的位置。更多信 息,查閱getOrientation()方法,getRotationMatrix()方法,Orientation Sensor,和Rotation Vector Sensor。 

 

訪問和使用傳感器的最佳實踐 

———————————————————————————————————————————— 

當你設計你的傳感器實現的時候,確保遵守這個章節下面討論的准則。這些准則是為任何使用傳感器框架訪問並獲取傳感器數據的人,推薦的最佳實踐。 

 

注銷傳感器監聽器 

當你完成使用傳感器的事情或者當傳感器activity pause的時候,確保注銷傳感器監聽器。如果一個傳感器的監聽器被注冊並且它的activity被pause,這個傳感器將繼續獲取數據並且使用電池資源,除非你注銷這個傳感器。下面的代碼展示了如何使用onPause()方法來注銷和注冊一個監聽器: 

[java] view plain copy
  1. private SensorManager mSensorManager;   
  2.   ...   
  3. @Override   
  4. protected void onPause() {   
  5.   super.onPause();   
  6.   mSensorManager.unregisterListener(this);   
  7. }   
更多信息,查閱unregisterListener(SensorEventListener)。 

 

不要在模擬器上測試你的代碼 

你目前不能再模擬器上測試你的傳感器代碼,因為模擬器不能模擬傳感器。你必須在一個物理設備上測試你的傳感器代碼。然后,有,你能使用傳感器模擬器來模擬傳感器輸出。 

 

不要阻塞onSensorChanged()方法 

傳 感器數據可以高速的變化,這意味着系統可能經常調用onSensorChanged(SensorEvent)方法。作為一項最佳的實踐,你應該竟可能少 的在onSensorChanged(SensorEvent)方法中做事情,所以你沒有阻塞它。如果你的應用程序要求你做任何數據過濾或者減少傳感器數 據,你應該在onSensorChanged(SensorEvent)方法外執行這個工作。 

 

避免使用過時的方法或者傳感器類型 

幾 個方法和常量已經被棄用。尤其,TYPE_ORIENTATION傳感器類型已經被棄用。為了獲取方向數據你應該使用getOrientation()方 法替代。同樣,TYPE_TEMPERATURE傳感器類型已經被棄用。你應該在運行Andorid4.0的設備上使用 TYPE_AMBIENT_TEMPERATURE傳感器類型替代。 

 

在你使用它們之前驗證傳感器 

在你嘗試從它獲取數據之前,總是驗證在一個傳感器在設備上是否存在。不要因為它是一個常用的傳感器而簡單假設傳感器存在。設備廠商沒有被要求在它們的設備上提供任何指定的傳感器。 

 

仔細選擇傳感器延遲 

當你使用registerListener()方法中注冊一個傳感器的時候,確保你選擇一個適合你的應用程序或者用例的分發率。傳感器能非常高速提供數據。允許系統發送額外的你不需要浪費系統資源並使用電池的數據。 

 

轉自:

http://blog.csdn.net/p106786860/article/details/16800467

原文:

http://developer.android.com/guide/topics/sensors/sensors_overview.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM