標籤:mit null 大致 存在 change 事件監聽器 發布 otto dcl
Android Sensor Development
本文我們說一下Android中的感應器,這對於我們有時候做一些特殊的應用的時候還是需要的,這裡我用小米手機下載了一個安兔兔,我們來看下大致的感應器
安兔兔上面,有很多的感應器對吧,但是他們大致的其實是分三類,在我們的官方文檔上,是這樣說的
sensors_overview
一.感應器概述
大多數Android裝置都具有測量運動,方向和各種環境條件的內建感應器。這些感應器能夠以高精度和精確度提供未經處理資料,如果要監視三維裝置移動或定位,或者想要監視裝置附近的環境環境中的變化,這些感應器很有用。例如,遊戲可以跟蹤來自裝置的重力感應器的讀數,以推斷複雜的使用者手勢和運動,例如傾斜,搖動,旋轉或擺動。同樣,天氣應用可能會使用裝置的溫度感應器和濕度感應器來計算和報告露點,或旅行應用程式可能會使用地磁場感應器和加速度計來報告羅盤方位。
Android平台支援三大類感應器:
這些感應器測量沿著三個軸的加速力和旋轉力。該類別包括加速度計,重力感應器,陀螺儀和旋轉向量感應器。
這些感應器測量各種環境參數,例如環境空氣溫度和壓力,照明和濕度。此類別包括氣壓計,光度計和溫度計。
這些感應器測量裝置的物理位置。該類別包括定向感應器和磁力計
上面說的天花亂墜,其實我們可以這樣去總結
- 方向 TYPE_ORIENTATION
- 加速 TYPE_ACCELEROMETER
- 光纖 TYPE_LIGHT
- 磁場 TYPE_MAGNETIC_FIELD
- 距離 TYPE_PROXIMITY
- 溫度 TYPE_TEMPERATURE
二.感應器架構
您可以使用Android感應器架構訪問這些感應器並擷取原始感應器資料。感應器架構是android.hardware包的一部分,包括以下類和介面:
您可以使用此類建立感應器服務的執行個體。該類提供了訪問和列出感應器,註冊和登出感應器事件監聽器以及擷取方向資訊的各種方法。該類還提供了幾個感應器常數,用於報告感應器精度,設定資料擷取率和校準感應器。
您可以使用此類建立特定感應器的執行個體。該類提供了各種可以確定感應器功能的方法。
系統使用此類建立感應器事件對象,該對象提供有關感應器事件的資訊。感應器事件對象包括以下資訊:原始感應器資料,建置事件的感應器類型,資料的準確性以及事件的時間戳記。
您可以使用此介面建立兩個回傳方法,當感應器值更改或感應器精度更改時接收通知(感應器事件)。
在典型的應用程式中,您可以使用這些與感應器相關的API執行兩個基本任務:
如果您的應用程式具有依賴於特定感應器類型或功能的功能,則在運行時識別感應器和感應器功能非常有用。例如,您可能想要識別裝置上存在的所有感應器,並禁用依賴於不存在的感應器的任何應用程式功能。同樣,您可能想要識別給定類型的所有感應器,因此您可以選擇具有最佳效能的感應器實現。
監控感應器事件是如何擷取原始感應器資料。每當感應器檢測到其測量參數的變化時,就會發生感應器事件。感應器事件為您提供四條資訊:觸發事件的感應器的名稱,事件的時間戳記,事件的準確性以及觸發事件的原始感應器資料。
三.感應器的可用性
雖然感應器可用性因裝置而異,但Android版本也可能有所不同。這是因為在幾個平台發布的過程中引入了Android感應器。例如,Android 1.5(API 3級)中引入了許多感應器,但有些沒有實現,直到Android 2.3(API Level 9)才能使用。同樣,Android 2.3(API 9級)和Android 4.0(API等級14)中引入了幾種感應器。兩個感應器已被棄用,並由更新更好的感應器代替。
表2總結了逐個平台的每個感應器的可用性。只列出了四個平台,因為這些是涉及感應器變化的平台。被列為不推薦使用的感應器仍然可以在隨後的平台上使用(感應器位於裝置上),這符合Android的前向相容性策略。
四.識別感應器和感應器能力
我們嘗試通過代碼來擷取裝置上的感應器,其實代碼是比較簡單的,我們來看一下
//擷取所有的感應器 private List<Sensor> getAllSensor() { SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); //這裡的Type就是我們需要擷取的感應器類型,這裡我擷取全部的 List<Sensor> mList = sensorManager.getSensorList(Sensor.TYPE_ALL); return mList; }
我們列印下
其實這個類型是一個實體類,也就是說我們依舊可以get單個元素,我這裡就全部列印出來了
除了列出裝置上的感應器之外,還可以使用Sensor該類的公用方法 來確定各個感應器的功能和屬性。如果您希望應用程式根據裝置上可用的感應器或感應器功能的不同而有所不同。例如,您可以使用getResolution()和getMaximumRange() 方法來擷取感應器的解析度和最大測量範圍。您還可以使用該 getPower()方法來擷取感應器的電源要求。
五.光線感應器
我們這裡,就列舉幾個代表性的感應器來說一下就好了,通過代碼個官方文檔來實踐
,我們來擷取光線感應器的速率
//光線感應器 private void LightSensor() { SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); /** * 註冊事件 * 回調 * 感應器 * 採樣率 */ sensorManager.registerListener(new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { //光線強度 float values = event.values[0]; tvResult.append(values + "\n"); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }, sensor, sensorManager.SENSOR_DELAY_UI); }
可以看到我這裡擷取到光線感應器之後我就註冊了一個監聽,而速率就是在裡面拿的
一般我們的自動調節亮度這種功能會需要到
使用感應器的時候一定要注意的就是資源的回收
@Override protected void onDestroy() { super.onDestroy(); if (sensorManager != null) { sensorManager.unregisterListener(listener); } }
這裡我們在銷毀的時候就取消了監聽
六.加速度感應器
加速度其實和光線感應器的代碼差不多,我們可以看一下
//加速度感應器 private void AccelerometerSensor() { Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); listener = new LightSensorListener(); sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_UI); }
我們的監聽器
class LightSensorListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { //0: x軸 1:y軸 2:z軸 float values0 = event.values[0]; float values1 = event.values[1]; float values2 = event.values[2]; //計算加速度 tvResult.append("x軸:"+values0 + "y軸:" + values1 + "z軸:" + values2 + "\n"); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
這樣就可以檢測了
從源碼中可以看到
我們可以根據這三個值去通過牛頓的第二定律去計算我們想要的值,或者套用自己專用的公式去操作等
七.方向感應器
寫三個感應器,其實都類似,我們把不同的寫法寫上,如果你不知道values的具體用法,可以直接點開values的源碼看他的注釋,找到對應的感應器就好了,我們來再看下方向,等下嘗試著自己實現一個指南針
同樣的,我們先實現代碼
//方向感應器 private void OrientationSensor() { Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); listener = new LightSensorListener(); sensorManager.registerListener(listener, sensor, sensorManager.SENSOR_DELAY_FASTEST); }
而我們的指南針的功能,也是通過這個監聽了
class LightSensorListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { //夾角度數 float values = event.values[0]; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
八.指南針
指南針的話,我們可以先吧UI實現
<RelativeLayout android:layout_width="200dp" android:layout_height="200dp"> <ImageView android:id="@+id/iv_point" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/iv_pointer"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="北" android:textColor="@android:color/background_dark" android:textSize="18sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="南" android:textColor="@android:color/background_dark" android:textSize="18sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:text="西" android:textColor="@android:color/background_dark" android:textSize="18sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="東" android:textColor="@android:color/background_dark" android:textSize="18sp"/> </RelativeLayout>
實現的效果
我們主要是怎麼來實現這個指標的動畫,這裡直接用了一個旋轉動畫
class LightSensorListener implements SensorEventListener { float lastValues = 0; @Override public void onSensorChanged(SensorEvent event) { //夾角度數 float values = event.values[0]; //tvResult.setText("夾角:" + values); /** * 0:東 * 90:南 * 180:西 * 270:北 */ RotateAnimation anim = new RotateAnimation( -lastValues, values, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); iv_point.startAnimation(anim); lastValues = values; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { }
這樣我們就實現了
好的,到這裡,我們的感應器就BB完了,有興趣的同學可以加群
Android旅行的路途:484167109
當然,你也可以關注我的公眾號
Sample下載:http://download.csdn.net/detail/qq_26787115/9829628
Android Sensor Development