JAVA 程式
我們使用 sensor 接口一般隻要注冊一下 SensorListener 像下面這樣
**************************************************************
ApiDemo:
mGraphView = new GraphView(this);
mSensorManager.registerListener(mGraphView,....);
這裡的 listener 是因為 sensor 狀态變化要産生變化的控件
然後在控件裡重載 on
SensorChanged 和 onAccuracyChanged 方法
public void onSensorChanged(int sensor, float[] values)
public void onAccuracyChanged(int sensor, int accuracy)
SensorManager
Sensor 主體代碼和流程在 frameworks/base/core/java/android/hardware/SensorManager.java 裡面
1.registerListener 其實是調用 registerLegacyListener:
public boolean registerListener(SensorListener listener, int sensors, int rate) {
...
result = registerLegacyListener(...);
}
2. registerLegacyListener 其實就是構造一個 LegacyListener 對象并将其加入 HashMap 中去
private boolean registerLegacyListener(int legacyType, int type,
SensorListener listener, int sensors, int rate)
{
legacyListener = new LegacyListener(listener);
mLegacyListenersMap.put(listener, legacyListener); //private HashMap<SensorListener,
LegacyListener> mLegacyListenersMap
3. LegacyListener 做了 2 件事 一個是調用我們重載的那 2 個接口 還有一個就是将 sensor 的
資料刷到我們的裝置顯示界面上去
private class LegacyListener implements SensorEventListener {
LegacyListener(SensorListener target) {
mTarget = target;
mSensors = 0;
public void onSensorChanged(SensorEvent event) {
mapSensorDataToWindow();
mTarget.onSensorChanged(...);//private SensorListener mTarget;
public void onAccuracyChanged(Sensor sensor, int accuracy) {
代碼最後是一些 native 方法:
private static native void nativeClassInit();//SensorManager 構造函數裡調用
private static native int sensors_module_init();//SensorManager 構造函數裡調用
private static native int sensors_module_get_next_sensor(Sensor sensor, int
next);//SensorManager 構造函數裡調用
// Used within this module from outside SensorManager, don't make private
static native int sensors_data_init();//SensorThread 構造裡調用
static native int sensors_data_uninit();//SensorThread 析構裡調用
static native int sensors_data_open(FileDescriptor fd); //SensorThread 的 run()循環調用
static native int sensors_data_close();//SensorThread 的 run()循環調用
static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);//SensorThread
的 run()循環調用
SensorManager 與 IsensorService 的關系
SensorManager 調用 IsensorService 其實隻是調用了 service 的方法來控制 thread 是 Lock
void startLocked(ISensorService service) {
ParcelFileDescriptor fd = service.getDataChanel();
或者打開
mSensorService.enableSensor(l, name, handle, delay);
IsensorService 的執行個體是這麼獲得的
mSensorService = ISensorService.Stub.asInterface(
ServiceManager.getService(Context.SENSOR_SERVICE));
IsensorService 是通過 aidl 定義的
interface ISensorService
ParcelFileDescriptor getDataChanel();
boolean enableSensor(IBinder listener, String name, int sensor, int enable);
SensorService
frameworks/base/services/java/com/android/server/SensorService.java
class SensorService extends ISensorService.Stub {
service 最終被 manager 調到走的是 android 的标準流程我們不 care,我們想知道的其實就是
enableSensor 的實作
首先,得有電
if (enable == SENSOR_DISABLE) {
mBatteryStats.noteStopSensor(uid, sensor);
} else {
mBatteryStats.noteStartSensor(uid, sensor);
看是不是能打開 sensor
if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
Log.w(TAG, "could not enable sensor " + sensor);
return false;
}
如果 sensor 打開了 我們要監聽狀态還要對外面報告狀态變化
if (l == null && enable!=SENSOR_DISABLE) {
l = new Listener(binder);
binder.linkToDeath(l, 0);
mListeners.add(l);
mListeners.notify();
如果 sensor 被關閉了 我們要取消監聽并且告訴外面關閉了傳感
if (enable != SENSOR_DISABLE) {
l.addSensor(sensor, enable);
} else {
l.removeSensor(sensor);
deactivateIfUnused(sensor);
if (l.mSensors == 0) {
mListeners.remove(l);
binder.unlinkToDeath(l, 0);
mListeners.notify();
}
另外還有一些喚醒和設定延遲的動作
if (mListeners.size() == 0) {
_sensors_control_wake();
if (minDelay >= 0) {
_sensors_control_set_delay(minDelay);
從上面可以看出來 對于底層而言隻要知道上層怎麼調用傳感的接口就好 是以最關心的還是
我标綠的 native 方法 上層的傳感流程其實比較簡單 就是标準的 service 管理和 notify 流程
private static native int _sensors_control_init();
private static native ParcelFileDescriptor _sensors_control_open();
private static native boolean _sensors_control_activate(int sensor, boolean activate);
private static native int _sensors_control_set_delay(int ms);
private static native int _sensors_control_wake();
native 方法
1. manager 部分
frameworks/base/core/jni/android_hardware_SensorManager.cpp
先看一眼它的方法注冊
static JNINativeMethod gMethods[] = {
{"nativeClassInit", "()V", (void*)nativeClassInit },
{"sensors_module_init","()I", (void*)sensors_module_init },
{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
(void*)sensors_module_get_next_sensor },
{"sensors_data_init", "()I", (void*)sensors_data_init },
{"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
{"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
{"sensors_data_close", "()I", (void*)sensors_data_close },
{"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
};
小貼一個例子作為代表
static jint
sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo)
jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
int fd = env->GetIntField(fdo, offset);
return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd
調用到最後其實都是用的 sSensorDevice 的方法
/*
* The method below are not thread-safe and not intended to be
*/
static sensors_data_device_t* sSensorDevice = 0;
2.service 部分
frameworks/base/services/jni/com_android_server_SensorService.cpp
{"_sensors_control_init", "()I", (void*) android_init },
{"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
{"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
{"_sensors_control_wake", "()I", (void*) android_data_wake },
{"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
然後上面的那些方法我就不一一貼了 給出一個例子 其實這麼實作的
static jboolean
android_activate(JNIEnv *env, jclass clazz, jint sensor, jboolean activate)
int active = sSensorDevice->activate(sSensorDevice, sensor, activate);
return (active<0) ? false : true;
是以最後調用的其實都是 sSensorDevice 的方法 其他的幾個也是這樣 sSensorDevice 是這個
(不是線程安全的)
* The method below are not thread-safe and not intended to be
*/
static sensors_control_device_t* sSensorDevice = 0;
3.繼續追 終于到了硬體層了 最後一切的方法其實就在這裡了
hardware/libhardware/include/hardware/sensor.h
struct sensors_control_device_t {
struct hw_device_t common;
/**
* Returns the fd which will be the parameter to
* sensors_data_device_t::open_data().
* The caller takes ownership of this fd. This is intended to be
* passed cross processes.
*
* @return a fd if successful, < 0 on error
*/
int (*open_data_source)(struct sensors_control_device_t *dev);
/** Activate/deactivate one sensor.
* @param handle is the handle of the sensor to change.
* @param enabled set to 1 to enable, or 0 to disable the sensor.
* @return 0 on success, negative errno code otherwise
int (*activate)(struct sensors_control_device_t *dev,
int handle, int enabled);
* Set the delay between sensor events in ms
*
* @return 0 if successful, < 0 on error
*/
int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);
/**
* Causes sensors_data_device_t.poll() to return -EWOULDBLOCK immediately.
int (*wake)(struct sensors_control_device_t *dev);
struct sensors_data_device_t {
struct hw_device_t common;
* Prepare to read sensor data.
* This routine does NOT take ownership of the fd
* and must not close it. Typically this routine would
* use a duplicate of the fd parameter.
* @param fd from sensors_control_open.
int (*data_open)(struct sensors_data_device_t *dev, int fd);
* Caller has completed using the sensor data.
* The caller will not be blocked in sensors_data_poll
* when this routine is called.
int (*data_close)(struct sensors_data_device_t *dev);
* Return sensor data for one of the enabled sensors.
* @return sensor handle for the returned data, 0x7FFFFFFF when
* sensors_control_device_t.wake() is called and -errno on error
int (*poll)(struct sensors_data_device_t *dev,
sensors_data_t* data);
最後一組函數
/** convenience API for opening and closing a device */
static inline int sensors_control_open(const struct hw_module_t* module,
struct sensors_control_device_t** device) {
return module->methods->open(module,
SENSORS_HARDWARE_CONTROL, (struct hw_device_t**)device);
static inline int sensors_control_close(struct sensors_control_device_t* device) {
return device->common.close(&device->common);
static inline int sensors_data_open(const struct hw_module_t* module,
struct sensors_data_device_t** device) {
SENSORS_HARDWARE_DATA, (struct hw_device_t**)device);
static inline int sensors_data_close(struct sensors_data_device_t* device) {
轉載于http://yueguc.iteye.com/blog/855450