<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-348  評(píng)論-598  文章-0  trackbacks-0

    大多數(shù)Android設(shè)備有內(nèi)置的傳感器,來(lái)測(cè)量運(yùn)動(dòng),方向和各種環(huán)境條件。這些傳感器能提供高精度和準(zhǔn)確度的原始數(shù)據(jù),如果你想監(jiān)控設(shè)備三維運(yùn)動(dòng)或者位置,或者你想監(jiān)控設(shè)備周圍的環(huán)境變化,是非常有用的。例如,游戲可能跟蹤設(shè)備重力傳感器的數(shù)據(jù),來(lái)推斷復(fù)雜的用戶首飾和動(dòng)作,例如傾斜,震動(dòng),旋轉(zhuǎn),或者振幅。同樣的,天氣應(yīng)用可能使用設(shè)備的溫度傳感器和濕度傳感器的數(shù)據(jù)來(lái)計(jì)算和報(bào)告結(jié)露點(diǎn),或者旅行應(yīng)用可能使用磁場(chǎng)傳感器和加速度傳感器來(lái)報(bào)告一個(gè)指南針?lè)轿弧?/span> 

     

    Android平臺(tái)支持三大類的傳感器: 

    • 位移傳感器 

    這些傳感器測(cè)量沿三個(gè)軸線測(cè)量加速度和旋轉(zhuǎn)。這類包含家加速度,重力傳感器,陀螺儀,和矢量傳感器。 

    • 環(huán)境傳感器 

    這些傳感器測(cè)量各種環(huán)境參數(shù),例如周圍的空氣溫度和壓力,光線,和濕度。這類包含氣壓,光線,和溫度傳感器。 

    • 位置傳感器 

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

     

    你能訪問(wèn)設(shè)備上可用的傳感器,并通過(guò)使用Android傳感器框架獲取原始傳感器數(shù)據(jù)。傳感器框架提供了一些類和接口,來(lái)幫助你執(zhí)行各種傳感器相關(guān)的任務(wù)。例如,你能使用傳感器框架做如下事情: 

    • 確定什么傳感器在設(shè)備上有效。 

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

    • 獲取原始數(shù)據(jù),并定義你獲取傳感器數(shù)據(jù)的最小速率。 

    • 注冊(cè)和注銷傳感器事件監(jiān)聽,來(lái)監(jiān)聽傳感器改變。 

     

    這個(gè)主題提供了在Android平臺(tái)上的傳感器的概覽。它也介紹了傳感器框架。 

     

    傳感器介紹 

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

    Android傳感器框架讓你訪問(wèn)許多類型的傳感器。這些傳感器的一些事基于硬件的,一些是基于軟件的。基于硬件的傳感器是內(nèi)嵌到手機(jī)或者平板中的物理元件,它們通過(guò)直接測(cè)量指定的環(huán)境屬性來(lái)得到它們的數(shù)據(jù),例如加速度,磁場(chǎng)強(qiáng)度,或者角度變化。基于軟件的傳感器不是物理設(shè)備,盡管它們模仿基于硬件的傳感器。基于軟件的傳感器從一個(gè)或更多基于硬件的傳感器獲取它們的數(shù)據(jù),并且有時(shí)候被稱為虛擬傳感器或者合成傳感器。線性加速度傳感器和重力傳感器是基于軟件傳感器的例子。表1總結(jié)了Android平臺(tái)支持的傳感器。 

     

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

     

    表1.Android平臺(tái)支持的傳感器類型 

    傳感器 

    類型 

    描述 

    常見用法 

    TYPE_ACCELEROMETER 

    硬件 

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

    運(yùn)動(dòng)檢測(cè)(震動(dòng),傾角等)。 

    TYPE_AMBIENT_TEMPERATURE 

    硬件 

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

    檢測(cè)空氣溫度。 

    TYPE_GRAVITY 

    軟件或硬件 

    以m/s2測(cè)量重力, 

    運(yùn)動(dòng)檢測(cè)(震動(dòng),傾角等)。 

    TYPE_GYROSCOPE 

    硬件 

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

    旋轉(zhuǎn)檢測(cè)(旋轉(zhuǎn),轉(zhuǎn)動(dòng)等)。 

    TYPE_LIGHT 

    硬件 

    以lx測(cè)量周圍的光線級(jí)別。 

    控制屏幕的亮度。 

    TYPE_LINEAR_ACCELERATION 

    軟件或硬件 

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

    檢測(cè)沿著一個(gè)軸向的加速度。 

    TYPE_MAGNETIC_FIELD 

    硬件 

    以u(píng)T測(cè)量周圍的三個(gè)物理軸線方向的磁場(chǎng)。 

    創(chuàng)建一個(gè)羅盤。 

    TYPE_ORIENTATION 

    軟件 

    測(cè)量設(shè)備所有三個(gè)物理軸線方向(x,y和x)的旋轉(zhuǎn)角度。當(dāng)使用Level 3的API的時(shí)候,你能通過(guò)使用重力傳感器和磁場(chǎng)傳感器,結(jié)合getRotatinMatrix()方法,獲取設(shè)備的傾斜矩陣和旋轉(zhuǎn)矩陣。 

    檢測(cè)設(shè)備的位置。 

    TYPE_PRESSURE 

    硬件 

    以hPa和mbar測(cè)量周圍空氣氣壓。 

    檢測(cè)空氣氣壓的改變。 

    TYPE_PROXIMITY 

    硬件 

     

    手機(jī)在通話時(shí)的位置。 

    TYPE_RELATIVE_HUMIDITY 

    硬件 

    一個(gè)百分比測(cè)量周圍相對(duì)濕度。 

    檢測(cè)結(jié)露點(diǎn),絕對(duì),和相對(duì)濕度。 

    TYPE_ROTATION_VECTOR 

    軟件或硬件 

    通過(guò)提供設(shè)備的三個(gè)旋轉(zhuǎn)矢量測(cè)量設(shè)備方向。 

    檢測(cè)運(yùn)動(dòng)和檢測(cè)旋轉(zhuǎn)。 

    TYPE_TEMPERATURE 

    硬件 

    以攝氏度測(cè)量設(shè)備的溫度。這個(gè)傳感器在不同設(shè)備實(shí)現(xiàn)不同,并且這個(gè)傳感器在API Level 14使用TYPE_AMBIENT_TEMPERATURE替代。 

    檢測(cè)溫度。 

    傳感器框架 

    你能訪問(wèn)這些傳感器,并通過(guò)使用Android傳感器框架獲取原始數(shù)據(jù)。Android傳感器框架式android.hardware包的一部分,包含下面的類和接口: 

    SensorManager 

    你能使用這個(gè)類來(lái)創(chuàng)建一個(gè)傳感器服務(wù)的實(shí)例。這個(gè)類提供了各種方法類訪問(wèn)和列舉傳感器,注冊(cè)和注銷傳感器事件監(jiān)聽,并獲取相應(yīng)的信息。這個(gè)類也提供了幾個(gè)傳感器的常量,用戶報(bào)告?zhèn)鞲衅鞯木_度,設(shè)置數(shù)據(jù)獲取速率,和校準(zhǔn)傳感器。 

    Sensor 

    你能使用這個(gè)類類創(chuàng)建一個(gè)指定傳感器的實(shí)例。這個(gè)類提供了各種方法讓你確定傳感器的功能。 

    SensorEvent 

    系統(tǒng)使用這個(gè)類來(lái)創(chuàng)建一個(gè)傳感器對(duì)象,它提供了關(guān)于傳感器事件的信息。一個(gè)傳感器事件包含一下信息:原始傳感器數(shù)據(jù),這類傳感器產(chǎn)生的事件,數(shù)據(jù)的準(zhǔn)確性,和事件的時(shí)間戳。 

    SensorEventListener 

    你能使用這個(gè)接口來(lái)創(chuàng)建兩個(gè)回掉方法,當(dāng)傳感器的值改變或者當(dāng)傳感器的精度改變的時(shí)候,它接受通知(傳感器事件)。 

     

    在一個(gè)典型的應(yīng)用程序中,你使用這些傳感器相關(guān)的API來(lái)執(zhí)行兩個(gè)基本任務(wù): 

    • 識(shí)別傳感器和傳感器的性能 

    如果你的應(yīng)用程序有功能依賴指定的類型的傳感器和功能,在運(yùn)行時(shí)識(shí)別傳感器和傳感器的功能是非常有用的。例如,你可能想識(shí)別設(shè)備上可用的所有傳感器,和禁用所有依賴不存在的傳感器的應(yīng)用程序功能。同樣,你可能想識(shí)別一個(gè)指定類型的所有傳感器,所以你能選擇這個(gè)傳感器來(lái)為你的應(yīng)用程序?qū)崿F(xiàn)最佳性能。 

     

    • 檢測(cè)傳感器事件 

    檢測(cè)傳感器事件是你如何獲取原始傳感器數(shù)據(jù)。傳感器事件每次發(fā)生的時(shí)候,傳感器檢測(cè)到它測(cè)量的參數(shù)的改變。傳感器事件給你提供了四個(gè)方面的信息:觸發(fā)這個(gè)事件的傳感器的名稱,事件的時(shí)間戳,事件的精準(zhǔn)度,和觸發(fā)事件的原始傳感器數(shù)據(jù)。 

     

    傳感器的可用性 

    由于傳感器可用性設(shè)備和設(shè)備之間不同,不同的Android版本也不同。這是因?yàn)锳ndroid的傳感器在過(guò)去的幾個(gè)版本都被介紹了。例如,一些傳感器在Android1.5(API Level 3)中被介紹,但是一些直到Android2.3(API Level 9)也沒(méi)有被實(shí)現(xiàn)可用。同樣的,多個(gè)傳感器在Android2.3(API Level 9)和Anroid4.0(API Level 14)被介紹。兩個(gè)傳感器被棄用,并且被新的,更好的替代。 

     

    表2概括了每個(gè)傳感器逐個(gè)平臺(tái)分析的可用性。僅僅四個(gè)平臺(tái)被列出是因?yàn)檫@些平臺(tái)包含傳感器的變化。被列出的傳感器被棄用仍可在后續(xù)的平臺(tái)可用(提供的傳感器在設(shè)備上存在),這符合Android向前兼容的策略。 

     

    表2.傳感器平臺(tái)的可用性 

    傳感器 

    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這個(gè)類型的傳感器在Android1.5(API Level 3)被添加,但是直到Android2.3(API Level 9)也不可用。 

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

     

    識(shí)別傳感器和傳感器的性能 

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

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

     

    為了識(shí)別在設(shè)備上的傳感器,你首先需要獲取傳感器服務(wù)的索引。為此,你通過(guò)調(diào)用getSystemService()方法并傳遞SENSOR_SERVICE參數(shù),創(chuàng)建SensorManager類的一個(gè)實(shí)例。例如: 

    1. private SensorManager mSensorManager;   
    2. ...   
    3. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
    下一步,你能通過(guò)調(diào)用getSensorList()方法,并使用TYPE_ALL常量獲取設(shè)備上所有傳感器列表。例如: 

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

     

    你也可以通過(guò)調(diào)用getDefaultSensor()方法并傳遞指定傳感器的類型常量,來(lái)確定在設(shè)備上一個(gè)指定類型的傳感器是否存在。如果設(shè)備上有超過(guò)一個(gè)指定類型的傳感器,一個(gè)傳感器必須被指定為默認(rèn)的傳感器。如果一個(gè)指定類型的傳感器默認(rèn)不存在,這個(gè)方法返回null,這意味著設(shè)備沒(méi)有這個(gè)類型的傳感器。例如,下面的代碼用來(lái)檢測(cè)在設(shè)備上是否有一個(gè)磁場(chǎng)計(jì): 

    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沒(méi)有要求設(shè)備制造商向它們的Android設(shè)備內(nèi)嵌所有類型的傳感器,所以設(shè)備會(huì)有一個(gè)廣泛的傳感器配置。 

     

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

     

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

    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. }   
    另一個(gè)有用的方法是getMinDelay()方法,它返回傳感器用來(lái)檢測(cè)數(shù)據(jù)的最小時(shí)間戳(以微妙)。任何getMinDelay()方法返回非零數(shù)值的傳感器是一個(gè)流式傳感器。流式傳感器定期檢測(cè)數(shù)據(jù),并在Andriod2.3(API Level 9)中被介紹。如果當(dāng)你調(diào)用getMinDelay()方法時(shí)傳感器返回0,它意味著傳感器不是一個(gè)流式傳感器,因?yàn)樗鼉H僅當(dāng)感應(yīng)的參數(shù)改變的時(shí)候報(bào)告數(shù)據(jù)。 

     

    getMinDelay()方法是非常有用的,因?yàn)樗屇愦_定了傳感器獲取數(shù)據(jù)最小速率。如果在你應(yīng)用程序中的某一個(gè)功能需要高數(shù)據(jù)獲取率或者一個(gè)流式傳感器,你能使用這個(gè)方法類確定是否這個(gè)傳感器滿足這些要求,然后相應(yīng)的啟動(dòng)或禁止你的應(yīng)用程序的相關(guān)功能。 

     

    當(dāng)心:傳感器的最大數(shù)據(jù)獲取率并不一定是這個(gè)傳感器框架給你的應(yīng)用程序發(fā)送傳感器數(shù)據(jù)的速率。傳感器框架通過(guò)傳感器事件報(bào)告數(shù)據(jù),并且多個(gè)因素影響你的應(yīng)用程序獲取傳感器事件的速率。更多信息查閱Monitoring Sensor Events。 

     

    監(jiān)測(cè)傳感器事件 

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

    為了監(jiān)測(cè)原始數(shù)據(jù)你需要實(shí)現(xiàn)兩個(gè)通過(guò)SensorEventListener接口定義的回掉方法: 

    • 傳感器精度的變化 

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

     

    • 傳感器報(bào)告一個(gè)新的值 

    在這種情況下系統(tǒng)調(diào)用onSensorChanged()方法,向你提供了一個(gè)SensorEvent對(duì)象,一個(gè)SensorEvent對(duì)象包含關(guān)于新的傳感器數(shù)據(jù)的信息,包括:數(shù)據(jù)的精度,傳感器產(chǎn)生的數(shù)據(jù),數(shù)據(jù)產(chǎn)生的時(shí)間戳,和傳感器記錄的新的數(shù)據(jù)。 

     

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

    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. }   
    在這個(gè)例子中,當(dāng)registerListener()方法被調(diào)用的時(shí)候,默認(rèn)的數(shù)據(jù)延遲(SENSOR_DELAY_NORMAL)被指定。數(shù)據(jù)延遲(或者取樣率)控制著通過(guò)onSensorChanged()回調(diào)方法向你的應(yīng)用程序發(fā)送傳感器事件的間隔。默認(rèn)的數(shù)據(jù)延遲使用2000000微秒,適合檢測(cè)標(biāo)準(zhǔn)的屏幕方向變化。你能指定其它的數(shù)據(jù)延遲,例如SENSOR_DELAY_GAME(20000微秒延遲),SENSOR_DELAY_UI(60000微秒延遲),或者SENSOR_DELAY_FASTEST(0微秒延遲)。在Android3.0(API Level 11)中你也能指定以一個(gè)絕對(duì)的數(shù)值(以微秒)指定延遲。 

     

    你指定的延遲僅僅是一個(gè)建議延遲。Android系統(tǒng)和其它應(yīng)用系統(tǒng)可以改變這個(gè)延遲。最好的方法,你應(yīng)該指定你可以指定的最大延遲,因?yàn)橄到y(tǒng)通常會(huì)使用一個(gè)比你指定的小的延遲(即,你應(yīng)該選擇最慢的采樣率,但是仍然滿足你的應(yīng)用程序的需求)。使用更大的延遲在處理器上強(qiáng)加更小的負(fù)載,因此耗能更低。 

     

    沒(méi)有公共的方法來(lái)測(cè)定傳感器框架向你的應(yīng)用程序發(fā)送傳感器事件的速率;然而,你可以使用時(shí)間戳,它和每個(gè)傳感器事件在幾個(gè)事件的基礎(chǔ)上計(jì)算采樣速率相關(guān)。一旦你設(shè)置了它,你不能改變采樣速率(延遲)。如果由于一些原因,你必須改變延遲,你將不得不注銷和注冊(cè)傳感器監(jiān)聽器。 

     

    同樣重要的是要注意這個(gè)例子使用onResume()和onPause()回調(diào)方法來(lái)注冊(cè)和注銷傳感器事件監(jiān)聽器。最為一項(xiàng)最好方法,你應(yīng)該總是在你不需要的時(shí)候禁用傳感器,尤其是當(dāng)你的Activity被Pause的時(shí)候。沒(méi)有這樣做可能在短短幾個(gè)小時(shí)之內(nèi)耗盡電池,因?yàn)橐恍﹤鞲衅饔泻艽蟮墓β室螅⑶視?huì)很快用完電池。當(dāng)屏幕關(guān)閉的時(shí)候系統(tǒng)將會(huì)自動(dòng)禁用傳感器。 

     

    處理不同的傳感器配置 

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

    Android沒(méi)有為設(shè)備指定一個(gè)標(biāo)準(zhǔn)的傳感器配置,這意味著設(shè)備廠商可以將任何它們想要的傳感器配置安裝到他們的的Android設(shè)備。造成一個(gè)結(jié)果,設(shè)備包含了在大范圍配置的各種傳感器。例如,Motorola Xoom有一個(gè)壓力傳感器,但是Samsung Nexus S沒(méi)有。同樣,Xoom和Nexus S有陀螺儀,但是HTC Nexus One沒(méi)有。如果你的應(yīng)用程序依賴于一個(gè)指定類型的傳感器看,你必須確保這個(gè)傳感器在設(shè)備上存在,以至于你的應(yīng)用程序能成功運(yùn)行。你有兩個(gè)選擇來(lái)確保一個(gè)給定的傳感器在設(shè)備上存在: 

    • 在運(yùn)行時(shí)檢測(cè)傳感器,并酌情啟動(dòng)或禁用應(yīng)用程序的功能 

    • 使用Google Play過(guò)濾器來(lái)規(guī)定制定傳感器配置的設(shè)備 

     

    每個(gè)選擇都在下面的章節(jié)被討論 

     

    在運(yùn)行時(shí)檢測(cè)傳感器 

    如果你的應(yīng)用程序使用一個(gè)指定的傳感器,但是不依賴它,你能使用傳感器框架在運(yùn)行時(shí)檢測(cè)傳感器,然后酌情禁用和啟動(dòng)應(yīng)用程序功能。例如,一個(gè)導(dǎo)航引用程序可能使用溫度傳感器,壓力傳感器,GPS傳感器,和磁場(chǎng)傳感器來(lái)顯示溫度,氣壓,位置和羅盤方位。如果設(shè)備沒(méi)有一個(gè)壓力傳感器,你能使用傳感器框架在運(yùn)行時(shí)檢測(cè)壓力傳感器的存在,然后你的應(yīng)用程序顯示壓力的UI的部分。例如,下面的代碼檢查設(shè)備上是否有一個(gè)壓力傳感器: 

    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過(guò)濾器來(lái)指定特定的傳感器配置 

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

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

     

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

     

    傳感器坐標(biāo)系 

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

    通常,傳感器框架使用一個(gè)標(biāo)準(zhǔn)的3維坐標(biāo)系來(lái)表達(dá)數(shù)據(jù)值。對(duì)于大多數(shù)傳感器,當(dāng)設(shè)備放置默認(rèn)的方向(看圖1)的時(shí)候,坐標(biāo)系被定義和設(shè)備的屏幕相關(guān)。當(dāng)設(shè)備放置為它默認(rèn)的方向,X軸是水平并指向右邊,Y軸是豎直并指向上方,并且Z軸指向屏幕面的外側(cè)。在這個(gè)系統(tǒng),坐標(biāo)系統(tǒng)有負(fù)的Z值。這個(gè)坐標(biāo)系被用于下面的傳感器: 

    • 加速度傳感器 

    • 重力傳感器 

    • 陀螺儀傳感器 

    • 線性加速度傳感器 

    • 磁場(chǎng)傳感器 

    圖1.傳感器API使用的坐標(biāo)系系統(tǒng)(相對(duì)于一個(gè)設(shè)備) 

     

    理解這個(gè)坐標(biāo)表系的最重要的一點(diǎn)是,當(dāng)設(shè)備屏幕的方向改變的時(shí)候,軸不改變—就是說(shuō),傳感器的坐標(biāo)系當(dāng)設(shè)備移動(dòng)的時(shí)候從來(lái)都不會(huì)改變。這個(gè)和OpenGL坐標(biāo)系是相同的。 

     

    理解的另一點(diǎn)是你的應(yīng)用程序不能假定設(shè)備的自然(默認(rèn))方向是豎屏。對(duì)于許多平板設(shè)備的自然方向是橫屏。并且傳感器的坐標(biāo)系總是急于設(shè)備的自然方向。 

     

    最終,如果你的應(yīng)用程序匹配傳感器數(shù)據(jù)到屏幕顯示,你需要使用getRotation()方法來(lái)確定屏幕的旋轉(zhuǎn),然后使用remapCoordinateSystem()方法來(lái)映射傳感器坐標(biāo)系到屏幕坐標(biāo)系。即使你的清單文件指定了僅僅豎屏幕顯示你也需要這樣做。 

     

    更多關(guān)于傳感器坐標(biāo)系的信息,包含如何處理屏幕旋轉(zhuǎn)的信息,查閱One Screen Turn Deserves Another。 

     

    注意:一些傳感器和方法使用的坐標(biāo)系是相對(duì)于真實(shí)世界的參照(相對(duì)于設(shè)備的參考框架)。這些傳感器和方法返回?cái)?shù)據(jù)代表設(shè)備的運(yùn)動(dòng)或者設(shè)備相對(duì)于地球的位置。更多信息,查閱getOrientation()方法,getRotationMatrix()方法,Orientation Sensor,和Rotation Vector Sensor。 

     

    訪問(wèn)和使用傳感器的最佳實(shí)踐 

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

    當(dāng)你設(shè)計(jì)你的傳感器實(shí)現(xiàn)的時(shí)候,確保遵守這個(gè)章節(jié)下面討論的準(zhǔn)則。這些準(zhǔn)則是為任何使用傳感器框架訪問(wèn)并獲取傳感器數(shù)據(jù)的人,推薦的最佳實(shí)踐。 

     

    注銷傳感器監(jiān)聽器 

    當(dāng)你完成使用傳感器的事情或者當(dāng)傳感器activity pause的時(shí)候,確保注銷傳感器監(jiān)聽器。如果一個(gè)傳感器的監(jiān)聽器被注冊(cè)并且它的activity被pause,這個(gè)傳感器將繼續(xù)獲取數(shù)據(jù)并且使用電池資源,除非你注銷這個(gè)傳感器。下面的代碼展示了如何使用onPause()方法來(lái)注銷和注冊(cè)一個(gè)監(jiān)聽器: 

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

     

    不要在模擬器上測(cè)試你的代碼 

    你目前不能再模擬器上測(cè)試你的傳感器代碼,因?yàn)槟M器不能模擬傳感器。你必須在一個(gè)物理設(shè)備上測(cè)試你的傳感器代碼。然后,有,你能使用傳感器模擬器來(lái)模擬傳感器輸出。 

     

    不要阻塞onSensorChanged()方法 

    傳感器數(shù)據(jù)可以高速的變化,這意味著系統(tǒng)可能經(jīng)常調(diào)用onSensorChanged(SensorEvent)方法。作為一項(xiàng)最佳的實(shí)踐,你應(yīng)該竟可能少的在onSensorChanged(SensorEvent)方法中做事情,所以你沒(méi)有阻塞它。如果你的應(yīng)用程序要求你做任何數(shù)據(jù)過(guò)濾或者減少傳感器數(shù)據(jù),你應(yīng)該在onSensorChanged(SensorEvent)方法外執(zhí)行這個(gè)工作。 

     

    避免使用過(guò)時(shí)的方法或者傳感器類型 

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

     

    在你使用它們之前驗(yàn)證傳感器 

    在你嘗試從它獲取數(shù)據(jù)之前,總是驗(yàn)證在一個(gè)傳感器在設(shè)備上是否存在。不要因?yàn)樗且粋€(gè)常用的傳感器而簡(jiǎn)單假設(shè)傳感器存在。設(shè)備廠商沒(méi)有被要求在它們的設(shè)備上提供任何指定的傳感器。 

     

    仔細(xì)選擇傳感器延遲 

    當(dāng)你使用registerListener()方法中注冊(cè)一個(gè)傳感器的時(shí)候,確保你選擇一個(gè)適合你的應(yīng)用程序或者用例的分發(fā)率。傳感器能非常高速提供數(shù)據(jù)。允許系統(tǒng)發(fā)送額外的你不需要浪費(fèi)系統(tǒng)資源并使用電池的數(shù)據(jù)。 



    ---------------------------------------------------------
    專注移動(dòng)開發(fā)

    Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian
    posted on 2015-11-18 15:33 TiGERTiAN 閱讀(700) 評(píng)論(0)  編輯  收藏 所屬分類: Android
    主站蜘蛛池模板: 亚洲精品无码鲁网中文电影| 国产成人无码区免费网站| 国产嫩草影院精品免费网址| 亚洲中文字幕无码mv| 老司机在线免费视频| 最新国产成人亚洲精品影院| 91网站免费观看| 亚洲日本国产综合高清| 18禁超污无遮挡无码免费网站国产| 亚洲熟妇无码AV| 免费无码黄网站在线观看| MM1313亚洲国产精品| 亚洲高清最新av网站| 夜夜爽妓女8888视频免费观看| 亚洲一区二区高清| a毛片免费全部播放完整成| 久久精品国产亚洲香蕉| 91免费国产精品| 亚洲av永久无码嘿嘿嘿| 女人张开腿等男人桶免费视频 | 亚洲美女视频免费| 亚洲免费电影网站| 免费黄色一级毛片| 免费无遮挡无遮羞在线看| 国产亚洲日韩在线三区| 久久午夜免费鲁丝片| 亚洲免费视频网址| 日韩成人在线免费视频| 日本在线观看免费高清| 国产V亚洲V天堂A无码| 中文字幕在线观看免费视频| 亚洲AV无码一区二区三区在线| 日本无卡码免费一区二区三区| 日韩电影免费在线观看网址| 亚洲乱亚洲乱妇无码麻豆| 97在线视频免费| 国内精品久久久久影院亚洲| 国产高清免费在线| 成人自慰女黄网站免费大全| 老司机亚洲精品影院| 18禁超污无遮挡无码免费网站国产|