如果想要調用系統的sensor,那就得用到系統自帶的sensorservice。一般的調用方法是.
先開啓服務:
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);//這個是light sensor的實例
然後聲明一個監聽函數
listen = new SensorEventListener(){
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
public void onSensorChanged(SensorEvent event) {//當sensor有事件時會發回一個消息;
}
}
當需要開啓sensor時。用mSensorManager.registerListener(mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);來註冊到sensorservice的列表中。
當需要關閉時,用 mSensorManager.unregisterListener(mSensorEventListener);實現取消註冊
在Java層Sensor的狀態控制由SensorService來負責,它的java代碼和JNI代碼分別位於:
frameworks/base/services/java/com/android/server/SensorService.java
frameworks/base/services/jni/com_android_server_SensorService.cpp
在Java層Sensor的數據控制由SensorManager來負責,它的java代碼和JNI代碼分別位於:
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
在java層中,當mSensorManager.registerListener(mSensorEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);時會跑到sensorManager.java中去。函數首先會判斷mSensorEventListener是否在當前的listen的列表中,
如果在直接mSensorService.enableSensor(l, name, handle, delay)打開sensor。如果不在那麼會將mSensorEventListener加入列表,然後判斷listen的列表是否爲空,如果是就會創建一個thread。sSensorThread.startLocked
(mSensorService)這個是sensor的核心,在這個線程中sensor會調用JNI的函數sensors_data_poll(values, status, timestamp)來一直poll,當有event的時候,sensorservice會將event發給對應的listener,
在JNI部分Android對於Sensor的API定義在 hardware/libhardware/include/hardware/sensor.h中, 要求在sensor.so提供以下8個API函數
[控制方面]
int (*open_data_source)(struct sensors_control_device_t *dev);
int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled);
int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);
int (*wake)(struct sensors_control_device_t *dev);
[數據方面]
int (*data_open)(struct sensors_data_device_t *dev, int fd);
int (*data_close)(struct sensors_data_device_t *dev);
int (*poll)(struct sensors_data_device_t *dev, sensors_data_t* data);
[模塊方面]
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
sensorService.cpp和sensorManger.cpp通過hardware.c與sensor.so通信。其中sensorService.cpp實現對sensor的狀態控制,sensorManger.cpp實現對sensor的數據控制。
sensor.so通過ioctl控制sensor driver的狀態,通過打開sensor driver對應的設備文件讀取G-sensor採集的數據
在sSensorThread.startLocked時,會先調用getDataChannel().這個在sensorservice中,然後調用_sensors_control_open()。此時反問JNI層的函數對應的是android_open。在android_open中系統通過native_handle_t* handle =
sSensorDevice->open_data_source(sSensorDevice);從sensor.cpp中獲得我們要打開sensor的fd還有其他的一些信息。對應硬件這塊具體操作是在sensor.cpp中完成的,包括data_open,data_close,sensor_poll等等上面提過的
shensor.so的api。
當創建一個thread後,會調用mSensorService.enableSensor(l, name, handle, delay)打開sensor。這個函數主要是調用_sensors_control_activate來激活sensor,這一切做完了,基本上就是等底層的poll循環給你發消息了。