Android驅動筆記(5)——Android傳感器框架


 使用Android傳感器框架訪問傳感器並獲取原始傳感器數據。傳感器框架可以做什么?

  1. 確定設備上可用的傳感器;
  2. 確定單個傳感器的功能,例如:量程,制造商,功率要求和分辨率等;
  3. 獲取原始數據並定義獲取數據的最小速率;
  4. 注冊和取消傳感器事件監聽。

 傳感器框架是android.hardware包的一部分,包括以下類和接口:

1、SensorManager:此類創建傳感器服務的實例,提供了各種方法來訪問和列出傳感器,注冊和取消注冊傳感器事件偵聽器以及獲取方向信息。該類還提供了幾個傳感器常數,用於報告傳感器精度,設置數據采集速率和校准傳感器。
2、Sensor:此類創建特定傳感器的實例。此類提供了各種方法,可用於確定傳感器的功能。
3、SensorEvent:此類創建傳感器事件對象,該對象提供有關傳感器事件的信息。傳感器事件對象包括以下信息:原始數據,生成事件的傳感器類型,數據的准確性以及事件的時間戳。
4、SensorEventListener:可以使用此界面創建兩個回調方法,以便在傳感器值更改或傳感器精度更改時接收通知(傳感器事件)。

 框架實現兩個基本任務:

5.1、識別傳感器和傳感器功能

 要識別設備上的傳感器,通過調用getSystemService()方法並傳入SENSOR_SERVICE參數來創建SensorManager類的實例。 例如:

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

 接下來,通過調用getSensorList()方法並使用TYPE_ALL常量來獲取設備上每個傳感器的列表。例如:

List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

 如果要列出一類型的所有傳感器,可以使用另一個常量,例如TYPE_GYROSCOPE、TYPE_LINEAR_ACCELERATION或TYPE_GRAVITY。
 如果設備具有多個給定類型的傳感器,必須將其中一個傳感器指定為默認傳感器。 如果給定類型的傳感器不存在默認傳感器,則方法調用返回null,意味着設備沒有該類型的傳感器。例如,以下代碼檢查設備上是否有Mag:

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success!
} else {
    // Failure!
}

 我們還可以使用Sensor類的公共方法來確定各個傳感器的功能和屬性。例如,可以使用getResolution()和getMaximumRange()方法來獲取傳感器的分辨率和最大測量范圍。
 如果想針對不同制造商的傳感器或不同版本的傳感器進行優化。例如,應用程序監控用戶手勢(傾斜和晃動),可以為特定供應商的重力傳感器創建一組數據過濾規則和優化,並為沒有重力傳感器,只有加速度計的設備創建另一組數據過濾規則和優化。
 以下代碼展示了如何使用getVendor()和getVersion()方法來執行此操作。示例中,我們正在尋找一種重力傳感器,將Google LLC列為供應商,版本號為3.如果設備上沒有該特定傳感器,我們會嘗試使用加速度計。

private SensorManager sensorManager;
private Sensor mSensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
    List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
    for(int i=0; i<gravSensors.size(); i++) {
        if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
           (gravSensors.get(i).getVersion() == 3)){
            // Use the version 3 gravity sensor.
            mSensor = gravSensors.get(i);
        }
    }
}
if (mSensor == null){
    // 使用加速度
    if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    } else{
        // 你的設備中沒有加速度傳感器
    }
}

getMinDelay()方法返回傳感器數據的最小時間間隔(以微秒為單位)。 任何為getMinDelay()返回非零值的傳感器都是流傳感器。
 流傳感器定期檢測數據。如果在調用getMinDelay()方法時傳感器返回零,則表示傳感器不工作在輪詢而是中斷或其他,這時僅在感測到的參數發生變化時才報告數據。
 如果應用程序中的某些功能需要高數據采集速率或流式傳感器,則可以使用此方法確定傳感器是否滿足這些要求,然后相應地啟用或禁用應用程序中的相關功能。

5.2、監控傳感器事件

 獲取原始數據的方式。
 每當傳感器檢測到其正在測量的參數發生變化時,就會發生傳感器事件。
 傳感器事件提供四條信息:觸發事件的傳感器名稱,事件的時間戳,事件的准確性以及觸發傳感器事件的原始數據。
 要監視原始數據,需要實現兩個SensorEventListener接口:onAccuracyChanged()和onSensorChanged()。每當發生以下情況時,Android系統都會調用這些方法:

  • 傳感器的精度發生變化:系統調用onAccuracyChanged()方法,提供已更改的Sensor對象的引用和傳感器的新精度。精度有四種:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH或SENSOR_STATUS_UNRELIABLE。
  • 傳感器報告新值:系統調用onSensorChanged()方法提供SensorEvent對象。SensorEvent對象包含有關新傳感器數據的信息,包括:數據的准確性,生成數據的傳感器,生成數據的時間戳以及傳感器記錄的新數據。

 以下代碼顯示如何使用onSensorChanged()方法監視光感的數據。此示例在text.xml中顯示原始數據,該文件在main.xml文件中定義為sensor_data.

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor mLight;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // 傳感器靈敏度變化后進行的動作
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        // 光感返回單個數值
        // 許多其他傳感器會返回3個值, 每個軸各一個
        float lux = event.values[0];
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

 在此示例中,調用registerListener()方法時指定默認數據延遲(SENSOR_DELAY_NORMAL)。數據延遲(或采樣率)控制傳感器事件通過onSensorChanged()回調方法發送到應用程序的時間間隔。例如SENSOR_DELAY_GAME(20,000微秒延遲),SENSOR_DELAY_UI(60,000微秒延遲)或SENSOR_DELAY_FASTEST(0微秒延遲)。指定的延遲僅是建議的延遲。
 Android系統和其他應用程序可以改變這種延遲。使用較大的延遲會降低處理器的負載,從而降低功耗。
 同樣重要的是要注意,此示例使用onResume()和onPause()回調方法來注冊和取消注冊傳感器事件偵聽器。應始終禁用不需要的傳感器,尤其是在活動暫停時。如果不這樣做,可能會在幾個小時內耗盡電池,因為某些傳感器具有相當大的功率要求並且可能會快速耗盡電池電量。屏幕關閉時,系統不會自動禁用傳感器


免責聲明!

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



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