隨著高科技的發展,手機的應用已經滲透到我們生活中的各個方面,手機中的各種應用比如:光線感應,跑步記錄儀,搖一搖,地圖等各種軟件的開發其實都少不了一種開發就是android 傳感器的開發。這篇文章將帶領大家系統認識傳感器的工作原理及開發。
一、Android傳感器原理及簡介
傳感器是一種物理裝置或生物器官,能夠探測、感受外界的信號、物理條件(如光、熱、濕度)或化學組成(如煙霧),并將探知的信息傳遞給其他裝置或器官。標準GB7665-1987對傳感器的定義是:“能感受規定的被測量并按照一定的規律轉換成可用信號的器件或裝置,通常由敏感元件和轉換元件組成。”傳感器是一種檢測裝置,能感受被測量的信息,并能將檢測感受到的信息,按一定規律轉換成為電信號或其他所需形式的信息輸出,以滿足信息的傳輸、處理、存儲、顯示、記錄和控制等要求。它是實現自動檢測和自動控制的首要環節。
在android系統中,當手機內置傳感器檢測到外界的環境變化后會引起相應的傳感器模塊電阻發生變化進而影響手機的部分電流和電量。Google封裝提供了對這些硬件操作的API,因此,我們熟練的掌握這些類和方法就可以進行傳感器的開發了。
Android系統所支持的傳感器類型
Android感應器Android Sensor是一款能夠展示當前手機狀態的應用,包括硬件信息、當前位置、加速計、陀螺儀、光感、磁場、定向、電池窗臺,聲壓,同時還可以進行多點觸控的測試。
大多數Android設備都會內置傳感器,用來測量運動,旋轉和環境條件(重力,溫度,濕度等),這些傳感器可以將采集到的高精度的數據上報給應用程序。們可以將傳感器想成是應用程序的外延,幫助我們設計出更加豐富和多元化的應用。Android 系統所支持的傳感器類型:
傳感器類型表
傳感器類型 對應值 傳感器名稱
TYPE_ACCELEROMETER 1 加速度
TYPE_MAGNETIC_FIELD 2 磁力
TYPE_ORIENTATION 3 方向
TYPE_GYROSCOPE 4 陀螺儀
TYPE_LIGHT 5 光線感應
TYPE_PRESSURE 6 壓力
TYPE_TEMPERATURE 7 溫度
TYPE_PROXIMITY 8 接近
TYPE_GRAVITY 9 重力
TYPE_GRAVITY 10 線性加速度
傳感器坐標系統
通常情況,傳感器框架使用標準的3軸坐標系統來表達數據值。對于大多數傳感器,坐標系統是相對與設備被保持在默認方向時的設備的屏幕來定義的。當設備被保持在默認方向時,X軸是水平向右、Y軸是垂直向上、Z軸是指向屏幕面板的外部。在這個系統中,背對著屏幕的Z軸坐標是負值。該坐標系統被加速度傳感器、重力傳感器、陀螺儀、線性加速度傳感器、磁力儀傳感器使用
要理解的重要的一點是,在設備屏幕的方向發生變化時,坐標系統的各坐標軸不會發生變化,也就是說傳感器的坐標系統不會因設備的移動而改變。這種行為與OpenGL坐標系統的行為相同。
另外要理解的一點是,應用程序不要假設設備的自然(默認)方向是縱向的。對于很多平板設備的自然方向是橫向的。傳感器坐標系統總基于設備的自然方向。
Android傳感器常用類和接口:
傳感器屬于Android應用的外延,Android應用不能直接對傳感器進行操作,Android對硬件的操作進行了封裝,提供給我們一些類和接口,我們通過類和接口來調用方法可以獲取傳感器上報的數據。Android傳感器開發中常用的類和接口有SensorManager、SensorEventListener、Sensor、SensorEvent。顧名思義,SensorManager就是所有傳感器的一個綜合管理類,包括了傳感器的種類、采樣率、精準度等。可以通過getSystemService方法來獲取一個SensorManager對象。類和接口的作用如下:
Android傳感器類和接口
類或接口 作用
SensorManager 1. 獲取手機內置傳感器列表
2. 注冊指定傳感器監聽器
3. 注銷監聽器
Sensor 1. 用來表示一個傳感器的類
2. 設置傳感器的能力
SensorEvent 1. 用來封裝傳感器上報數據的類
SensorEventListener 1. 用來監聽傳感器上報數據的監聽器接口
Android傳感器的功能
要在Android中使用傳感器,首先要了解SensorManager和SensorEventListener。顧名思義,SensorManager就是所有傳感器的一個綜合管理類,包括了傳感器的種類、采樣率、精準度等。可以通過getSystemService方法來獲取一個SensorManager對象。
代碼清單1 獲取SensorManager對象
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
取得SensorManager對象之后,可以通過getSensorList方法來獲取我們所需的傳感器類型,保存到一個傳感器列表中。
代碼清單2 getSensorList
List
mSensorManager.getSensorList(Sensor.TYPE_ALL);
SensorManager還有很多的常量以及一些常用的方法。
SensorManager常用方法
方法 說明
getDefaultSensor 得到默認的傳感器對象
getInclination 得到地磁傳感器傾斜角的弧度
getOrientation 得到設備的旋轉方向
getSensorList 得到指定傳感器的列表
要與傳感器進行交互,應用程序必須注冊以偵聽與一個或多個傳感器相關的活動。Android中提供了registerListener來注冊一個傳感器,并提供了unregisterListener來卸載一個傳感器。registerListener方法包括三個參數:第一個參數是接收信號的Listener實例;第二個參數是想接收的傳感器類型的列表(上一步創建的List
代碼清單3 注冊和卸載傳感器
//注冊傳感器
Boolean mRegisteredSensor = mSensorManager.registerListener (this, sensor, SensorManager.SENSOR_DELAY_FASTEST);
//卸載傳感器
mSensorManager.unregisterListener(this);
其中,SensorEventListener是使用傳感器的核心部分,包括以下兩個必須實現的方法: onSensorChanged(SensorEvent event)方法在傳感器值更改時調用。該方法只有受此應用程序監視的傳感器調用。參數包括一個SensorEvent對象。該對象包括一組浮點數,表示傳感器獲得的方向、加速度等信息。代碼清單4所示的代碼可以取得其值。
代碼清單4 獲取傳感器獲取信息
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
onAccuracyChanged(Sensor sensor,int accuracy)方法在傳感器的精準度發生改變時調用。參數包括兩個整數:一個表示傳感器,另一個表示該傳感器新的準確值。
二、常用傳感器
1. 方向傳感器
一般情況下,在Android系統中對應的字段常量是TYPE_ORIENTATION,得到方向傳感器在方向傳感器中values變量的3個值都表示度數,他們的含義如下:
values[0]:該值表示方位,也就是手機繞著Z軸旋轉的角度。0表示北(North);90表示東(East);180表示南(South);270表示西(West)。如果values[0]的值正好是這4個值,并且手機是水平放置,表示手機的正前方就是這4個方向。電子羅盤就是利用這個特性來實現的。
values[1]:該值表示傾斜度,或手機翹起的程度。當手機繞著X軸傾斜時該值發生變化。values[1]的取值范圍是-180≤values[1]≤180。假設將手機屏幕朝上水平放在桌子上,這時如果桌子是完全水平的,values[1]的值應該是0(由于很少有桌子是絕對水平的,因此,該值很可能不為0,但一般都是-5和5之間的某個值)。
values[2]:表示手機沿著Y軸的滾動角度。取值范圍是-90≤values[2]≤90。假設將手機屏幕朝上水平放在桌面上,這時如果桌面是平的,values[2]的值應為0。將手機左側逐漸抬起時,values[2]的值逐漸變小,直到手機垂直于桌面放置,這時values[2]的值是-90。將手機右側逐漸抬起時,values[2]的值逐漸增大,直到手機垂直于桌面放置,這時values[2]的值是90。在垂直位置時繼續向右或向左滾動,values[2]的值會繼續在-90至90之間變化。
2. 磁力傳感器
磁力傳感器簡稱為M-sensor,在Android 中對應的字段常量是TYPE_MAGNETIC_FIELD,該傳感器主要讀取的是磁場的變化,通過該傳感器便可開發出指南針、羅盤等磁場應用。返回x、y、z三軸的環境磁場數據。該數值的單位是微特斯拉(micro-Tesla),用uT表示,單位也可以是高斯(Gauss)。
values[1]:該值表示x方向的磁場分量
values[2]: 該值表示y方向的磁場分量
values[3]: 該值表示z方向的磁場分量
3. 溫度傳感器
溫度傳感器返回當前的溫度,在Android 中對應的字段常量是TYPE_TEMPERATURE。此傳感器返回值只有一個值表示當前溫度,單位是攝氏度。
values[0]:當前溫度
4. 加速度傳感器
加速度傳感器用來測量加速度,在Android 中對應的字段常量是TYPE_ACCELEROMETER,在該傳感器上獲取的values變量的3個元素值分別表示X、Y、Z軸的加速值。例如,水平放在桌面上的手機從左側向右側移動,values[0]為負值;從右向左移動,values[0]為正值。讀者可以通過本節的例子來體會加速傳感器中的值的變化。
values[1]:該值表示x方向的加速度分量
values[2]: 該值表示y方向的加速度分量
values[3]: 該值表示z方向的加速度分量
5. 光傳感器
光線傳感器用來測量當前環境的光線,在Android 中對應的字段常量是TYPE_LIGHT。values數組只有第一個元素(values[0])有意義。表示光線的強度。大的值是120000.0f。Android SDK將光線強度分為不同的等級,每一個等級的大值由一個常量表示,這些常量都定義在SensorManager類中,代碼如代碼清單5所示:
代碼清單5 光線強度等級
public static final float LIGHT_SUNLIGHT_MAX =120000.0f;
public static final float LIGHT_SUNLIGHT=110000.0f;
public static final float LIGHT_SHADE=20000.0f;
public static final float LIGHT_OVERCAST= 10000.0f;
public static final float LIGHT_SUNRISE= 400.0f;
public static final float LIGHT_CLOUDY= 100.0f;
public static final float LIGHT_FULLMOON= 0.25f;
public static final float LIGHT_NO_MOON= 0.001f;
上面的八個常量只是臨界值。讀者在實際使用光線傳感器時要根據實際情況確定一個范圍。例如,當太陽逐漸升起時,values[0]的值很可能會超過LIGHT_SUNRISE,當values[0]的值逐漸增大時,就會逐漸越過LIGHT_OVERCAST,而達到LIGHT_SHADE,當然,如果天特別好的話,也可能會達到LIGHT_SUNLIGHT,甚至更高。
三、傳感器開發步驟
所有的程序開發都有一定的邏輯和步驟,傳感器的開發也不例外,傳感器開發共有3個步驟,下面以加速度傳感器為例來演示傳感器開發的三個具體步驟:
1.獲取傳感器管理器對象、傳感器對象,具體代碼如代碼清單6
代碼清單6 獲取傳感器管理器和傳感器對象
//獲取傳感器管理器 SensorManager
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
//獲取加速度傳感器 Sensor
Sensor accelerometerSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
2.定義傳感器事件,獲取響應數據,具體代碼如代碼清單7
代碼清單7 定義傳感器事件獲取上報數據
//定義傳感器事件監聽器
SensorEventListener accelerometerListener = new SensorEventListener() {
//當Sensor上報的數據發生改變時,onSensorChanged被調用
public void onSensorChanged(SensorEvent event) {
//上報的數據會保存在values屬性中
float x = event.values[SennsorManager.DATA_X]
float y = event.values[SennsorManager.DATA_Y]
float z = event.values[SennsorManager.DATA_Z]
//x,y,z變量是從加速度傳感器獲取的數據
}
//當Sensor精度被改變時,onAccuracyChanged被調用
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, mSensor, SensorManager.SENSOR_DELAY_NORMAL, null);
3.注冊(應用)傳感器事件,具體代碼如代碼清單8
代碼清單8 定義傳感器事件獲取上報數據
//在傳感器管理器中注冊監聽器
mSensorManager.registerListener(accelerometerListener, accelerometerSensor,SensorManager.SENSOR_DELAY_NORMAL);
四、開發案例
下面我們將通過兩個開發案例來練習傳感器的開發使用
案例一、光傳感器的應用
需求:在手機屏幕上實時顯示當前環境的光線的強弱值
布局文件里只有一個TextView,非常簡單,這里就不再粘貼代碼,java代碼具體實現代碼
如下代碼清單9所示:
代碼清單9 定義傳感器事件獲取上報數據
public class MainActivity extends Activity {
TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview = (TextView) findViewById(R.id.textview);
/**
* 需求:獲取特定傳感器上的上報數據
* 1.獲取特定的傳感器
* 2.給傳感器設置監聽
* 3.獲取上報數據
* */
//獲取特定的傳感器:通過管理器找到特定的傳感器
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
//獲取光傳感器
Sensor lightSensor = sm.getDefaultSensor(Sensor.TYPE_LIGHT);
//給傳感器注冊監聽器
/**
* 第一個參數:傳感器的監聽器
* 第二個參數:給哪個傳感器設置監聽
* 第三個參數:采樣率,即多久進行一次采樣
* */
sm.registerListener(new MyListener(), lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
/**
* 傳感器的監聽器,可以監聽傳感器的數據變化,上報數據
* */
class MyListener implements SensorEventListener{
/**
* 傳感器上報數據發生變化時調用的方法
* */
@Override
public void onSensorChanged(SensorEvent event) {
//獲取上報數據的數組,在光線傳感器中只有一個values[0],代表了當前光線強度
float[] values = event.values;
textview.setText("當前光線為:"+values[0]);
}
/**
* 傳感器精度發生變化時調用的方法
* */
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
}
這里只是舉例一個非常簡單的利用光傳感器的案例,讀者有興趣還可以實現通過加速度傳感器實現搖一搖的功能。