二十四、感測器
一、感測器 以工作方式分類,感測器可以分成基於硬體的感測器(hardware-based sensor)與基於軟體的感測器(software-based sensor)。 於硬體的感測器是內建在行動裝置上的實際元件,它們以直接量測特定環境因素而取得資料,例如加速計、光度計等。 基於軟體的感測器則是硬體感測器的模擬,並沒有真正的實體,它們提供的資料是取自硬體感測器,並經過運算、過濾或與其他感測器資料結合等處理而產生。
如果以感測器的功能分類,Android系統支援的感測器可以分成以下3類: 位置感測器(Position sensor):這一類感測器量測行動裝置的實際位置,例如方位感測器(Orientation sensor)、磁力計(Magnetometer)等。 運動感測器(Motion sensor):量測行動裝置3個軸向的加速度或角速度,例如加速計(Accelerometer)、陀螺儀(Gyroscope)等。 環境感測器(Environmental sensor):量測行動裝置所在環境的不同環境參數,像是量測環境溫度的溫度感測器(Temperature sensor)、量測環境亮度的亮度計(Photometer)等。
二、感測器應用程式開發步驟 Android SDK提供了相當完備的感測器開發框架與介面、類別,這些介面與類別都位於「android.hardware」套件中,主要有以下幾項: SensorManager 此類別用以建立感測器服務的實體,因此是以Context的「getSystemService(Context.SENSOR_SERVICE)」方法取得。
要存取指定的感測器,可以透過「getDefaultSensor(int type)」方法,或用「getSensorList(int type)」方法取得行動裝置中所有可以使用的指定型式感測器清單。 SensorManager sensorManager=(SensorManager) context.getSystemService(Context.SENSOR_SERVICE); Sensor accelerometer=sensorManager.getDefaultSensor (Sensor.TYPE_ACCELEROMETER); Sensor 此類別就表示一個感測器,提供有代表各種感測器型式的常數,以及一些可以取得感測器能力的方法。 SensorEvent 此類別是用以建立感測器事件的物件,它以欄位儲存一些與感測事件相關的資訊。
SensorEventListener 此介面的作用是在感測器量測的值發生改變,或是感測器精度發生改變時,接受系統的通知。 實作此介面時必須實作它的2個抽象方法,「onSensorChanged(SensorEvent event)」方法是感測器量測值改變時,由系統回呼的方法;「onAccuracyChanged(Sensor sensor, int accuracy)」方法是對指定感測器設定新的精度時,由系統回呼的方法。 為感測器登錄事件偵聽器時,需要設定事件的延遲(即事件觸發的頻率),這延遲設定相當重要,設定的太頻繁會耗用太多電力,設定頻率太低則可能會降低量測的準確度。此延遲一般是藉由SensorManager類別的常數設定,可以設定的常數有:
SENSOR_DELAY_NORMAL:200000微秒,是預設的觸發頻率,適合用於偵聽螢幕方位改變的事件。 SENSOR_DELAY_UI:60000微秒,適合用於偵聽使用者介面的事件。 SENSOR_DELAY_GAME:20000微秒,適合用於偵聽遊戲中的事件。 SENSOR_DELAY_FASTEST:0微秒,表示以系統最大的能力盡快更新量測資料。
感測器使用的座標系統
感測器應用程式建置架構如下: 用「getSystemService()」方法從系統取得感測器服務的實體。 用「getDefaultSensor()」或「getSensorList()」方法取得要使用感測器的參考。 實作SensorEventListener介面,並依程式的目的設計onSensorChanged(SensorEvent event)與onAccuracyChanged(Sensor sensor, int accuracy)回呼方法。 用「registerListener()」方法登錄感測器事件的偵聽器,一般會在活動的onResume()方法中登錄偵聽器。
當不再需要使用感測器的時候,用「unregisterListener()」方法取消對感測器事件偵聽器的登錄,這一般建議放在活動的onPause()方法中處理。 SensorsList Test範例 以ListView元件顯示行動裝置上可以使用的所有感測器;當使用者敲清單上任何一個感測器,程式將以Toast物件顯示此感測器的名稱、型式(數字代碼)、製造商等訊息。 範例詳細內容請參考原書。
三、位置感測器應用 Android系統主要以地磁場感測器(geomagnetic field sensor)與方位感測器(orientation sensor)決定行動裝置的位置,另以近接感測器(proximity sensor)判斷行動裝置的螢幕有多接近一個物體。 地磁場感測器 地磁場感測器量測對地球磁場的變化,是基於硬體的感測器。
它在一個感測事件中提供3個軸向的磁場值,分別以SensorEvent. values[0]表示X軸、SensorEvent 它在一個感測事件中提供3個軸向的磁場值,分別以SensorEvent.values[0]表示X軸、SensorEvent.values[1]表示Y軸、SensorEvent.values[2]表示Z軸的磁場強度。 private SensorManager sensorManager; private Sensor sensor; ..... sensorManager = (SensorManager)getSystemService (Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor (Sensor.TYPE_MAGNETIC_FIELD); …..
近接感測器 近接感測器也是基於硬體的感測器,主要作用是決定一個物體與行動裝置的距離,它在一個感測事件中,只提供一個量測值。 private SensorManager sensorManager; private Sensor sensor; ..... sensorManager = (SensorManager)getSystemService (Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor (Sensor. TYPE_PROXIMITY); …..
方位感測器 方位感測器可以用來偵測行動裝置相對於地磁北的位置,是基於軟體的感測器,它的資料來自加速計與地磁場感測器。方位感測器在一個感測事件中也同時提供3個軸向的方位角,分述如下: 擺動角(Yaw),存於SensorEvent.values[0]中;是繞Z軸轉動後,行動裝置Y軸與磁北之間的夾角,以Y軸朝X軸方向轉動為正,因此當行動裝置Y軸指向磁北時,此角度為0,指向東方時為90度,值的範圍0~360。 抬頭角(Pitch),存於SensorEvent.values[1]中;是繞X軸轉動的角度,以Y軸朝Z軸方向轉動為正,值的範圍180~-180。
滾動角(Roll),存於SensorEvent.values[2]中;是繞Y軸轉動的角度,以Z軸朝X軸方向轉動為正,值的範圍90~-90。 private SensorManager sensorManager; private Sensor sensor; ..... sensorManager = (SensorManager)getSystemService (Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor (Sensor. TYPE_ORIENTATION); …..
Compass Test範例 以方位感測器的擺動角旋轉螢幕上的羅盤圖形,使羅盤的指針指向北方。 範例詳細內容請參考原書。
四、運動感測器應用 運動可以是來自使用者的操作,例如使用者搖動,這類型的運動是相對於裝置本身座標系統的運動;運動也可以是因為行動裝置所處環境造成,例如行動裝置隨著使用者移動,這類型的運動則是相對於實際環境的位置變化。
線性加速計(Linear Accelerometer) 加速計量測行動裝置在3個軸所承受的加速度,其中SensorEvent.values[0]表示X軸的值、SensorEvent.values[1]為Y軸的值、SensorEvent.values[2]為Z軸的值,量測值包括重力影響。 使用時必須指定「TYPE_ACCELEROMETER」型式常數。 線性加速計(Linear Accelerometer) 與加速計主要的差別是它的量測值已經將重力影響扣除,另外線性加速計是基於軟體的感測器。
旋轉向量感測器(Rotation Vector Sensor) 使用時必須指定「TYPE_LINEAR_ACCELERATION」型式常數。 陀螺儀(Gyroscope) 陀螺儀量測繞行動裝置3個軸旋轉的角速度,使用時必須指定「TYPE_GYROSCOPE」型式常數。 旋轉向量感測器(Rotation Vector Sensor) 當行動裝置繞它的一個軸旋轉一個角度時,旋轉向量感測器的量測值是以此軸和角度的組合表示裝置的方位,分別以x×sin(θ/2)、y×sin(θ/2)、z×sin(θ/2)表示,其中旋轉向量的大小為「sin(θ/2)」。其座標系統定義如下:
重力感測器(Gravity Sensor) X為Y和Z的向量積(外積),與裝置目前位置地表相切且指向東方。 Y與裝置目前位置地表相切且指向北方。 Z與裝置目前位置地表垂直且指向天空。 使用時必須指定「TYPE_ROTATION_VECTOR」型式常數。 重力感測器(Gravity Sensor) 以3維向量指示重力的方向與大小,使用時必須指定「TYPE_GRAVITY」型式常數。 RollingBall Test範例 用加速計做個簡單方向控制的展示。
一開始有一個球位於螢幕中央,當使用者轉動行動裝置時,這個球會朝向行動裝置低的位置滾動。 範例詳細內容請參考原書。
五、環境感測器應用 Android系統提供的環境感測器共有5種:行動裝置溫度感測器(量測裝置本身的溫度)、環境溫度感測器(量測裝置四周的環境溫度)、相對濕度感測器、壓力感測器與光度計。 共同特性是,它們都是基於硬體的感測器,而且在一個感測事件中只提供一筆資料,但仍然是以陣列的形式提供。
SensorManager為各感測器定義的型式常數如下: 裝置溫度感測器:TYPE_TEMPERATURE 環境溫度感測器:TYPE_AMBIENT_TEMPERATURE 相對濕度感測器:TYPE_RELATIVE_HUMIDITY 壓力感測器:TYPE_PRESSURE 光度計:TYPE_LIGHT LightSensor Test範例 是單純的展示光度計的使用。 範例詳細內容請參考原書。