Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3003773
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2011-05-23 21:52:13

 这里的 listener 是因为 sensor 状态变化要产生变化的控件

  然后在控件里重载 on
  SensorChanged 和 onAccuracyChanged 方法

Java代码:
  1. public void onSensorChanged(int sensor, float[] values)
  2. public void onAccuracyChanged(int sensor, int accuracy)
复制代码

       SensorManager

  Sensor 主体代码和流程在 frameworks/base/core/java/android/hardware/SensorManager.java 里面
  1.registerListener 其实是调用 registerLegacyListener:

Java代码:
  1. public boolean registerListener(SensorListener listener, int sensors, int rate) {
  2. ...
  3. result = registerLegacyListener(...);
  4. ...
  5. }
复制代码

       2. registerLegacyListener 其实就是构造一个 LegacyListener 对象并将其加入 HashMap 中去

Java代码:
  1. private boolean registerLegacyListener(int legacyType, int type,SensorListener listener, int sensors, int rate){
  2. ...
  3. legacyListener = new LegacyListener(listener);
  4. mLegacyListenersMap.put(listener, legacyListener);  
  5. LegacyListener> mLegacyListenersMap
  6. ...
  7. }
复制代码

       3. LegacyListener 做了 2 件事 一个是调用我们重载的那 2 个接口 还有一个就是将 sensor 的数据刷到我们的设备显示界面上去

Java代码:
  1. private class LegacyListener implements SensorEventListener {
  2. ...
  3. LegacyListener(SensorListener target) {
  4. mTarget = target;
  5. mSensors = 0;
  6. }
  7. public void onSensorChanged(SensorEvent event) {
  8. ...
  9. mapSensorDataToWindow();
  10. mTarget.onSensorChanged(...);
  11. ...
  12. }

  13. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  14. ...
  15. }

  16. }
复制代码

      代码最后是一些 native 方法:

Java代码:
  1. private static native void nativeClassInit();//SensorManager 构造函数里调用
  2. private static native int sensors_module_init();//SensorManager 构造函数里调用
  3. private static native int sensors_module_get_next_sensor(Sensor sensor, intnext);//SensorManager 构造函数里调用

  4. static native int sensors_data_init();//SensorThread 构造里调用
  5. static native int sensors_data_uninit();//SensorThread 析构里调用
  6. static native int sensors_data_open(FileDescriptor fd); //SensorThread 的 run()循环调用
  7. static native int sensors_data_close();//SensorThread 的 run()循环调用
  8. static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);
  9. //SensorThread的run()循环调用
复制代码

       SensorManager 与 IsensorService 的关系  SensorManager 调用 IsensorService 其实只是调用了 service 的方法来控制 thread 是 Lock

Java代码:
  1. void startLocked(ISensorService service) {
  2. ...
  3. ParcelFileDescriptor fd = service.getDataChanel();
  4. ...
  5. }
复制代码

或者打开

Java代码:
  1. mSensorService.enableSensor(l, name, handle, delay);
复制代码

     IsensorService 的实例是这么获得的

Java代码
  1. mSensorService = ISensorService.Stub.asInterface(ServiceManager.getService(Context.SENSOR_SERVICE));
复制代码

     IsensorService 是通过 aidl 定义的

Java代码:
  1. interface ISensorService{
  2. ParcelFileDescriptor getDataChanel();
  3. boolean enableSensor(IBinder listener, String name, int sensor, int enable);
  4. }
复制代码

       SensorService

Java代码:
  1. class SensorService extends ISensorService.Stub {
  2. ...
  3. }
复制代码

       service 最终被 manager 调到走的是 android 的标准流程我们不 care,我们想知道的其实就是  enableSensor 的实现

Java代码:
  1. if (enable == SENSOR_DISABLE) {
  2. mBatteryStats.noteStopSensor(uid, sensor);
  3. } else {
  4. mBatteryStats.noteStartSensor(uid, sensor);
  5. }
复制代码

       看是不是能打开 sensor

Java代码:
  1. if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
  2. Log.w(TAG, "could not enable sensor " + sensor);
  3. return false;
  4. }
复制代码

       如果 sensor 打开了 我们要监听状态还要对外面报告状态变化

Java代码:
  1. if (l == null && enable!=SENSOR_DISABLE) {
  2. l = new Listener(binder);
  3. binder.linkToDeath(l, 0);
  4. mListeners.add(l);
  5. mListeners.notify();
  6. }
复制代码

  如果 sensor 被关闭了 我们要取消监听并且告诉外面关闭了传感

Java代码:
  1. if (enable != SENSOR_DISABLE) {
  2. l.addSensor(sensor, enable);
  3. } else {
  4. l.removeSensor(sensor);
  5. deactivateIfUnused(sensor);
  6. if (l.mSensors == 0) {
  7. mListeners.remove(l);
  8. binder.unlinkToDeath(l, 0);
  9. mListeners.notify();
  10. }

  11. }
复制代码

       另外还有一些唤醒和设置延迟的动作

Java代码:
  1. if (mListeners.size() == 0) {
  2. _sensors_control_wake();
  3. }


  4. if (minDelay >= 0) {
  5. _sensors_control_set_delay(minDelay);
  6. }
复制代码

       从上面可以看出来 对于底层而言只要知道上层怎么调用传感的接口就好 所以最关心的还是。我标绿的 native 方法 上层的传感流程其实比较简单 就是标准的 service 管理和 notify 流程

Java代码:
  1. private static native int _sensors_control_init();
  2. private static native ParcelFileDescriptor _sensors_control_open();
  3. private static native boolean _sensors_control_activate(int sensor, boolean activate);
  4. private static native int _sensors_control_set_delay(int ms);
  5. private static native int _sensors_control_wake();
复制代码

        native 方法
    1. manager 部分
  frameworks/base/core/jni/android_hardware_SensorManager.cpp先看一眼它的方法注册

Java代码:
  1. static JNINativeMethod gMethods[] = {
  2. {"nativeClassInit", "()V", (void*)nativeClassInit },
  3. {"sensors_module_init","()I", (void*)sensors_module_init },
  4. {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",(void*)sensors_module_get_next_sensor },
  5. {"sensors_data_init", "()I", (void*)sensors_data_init },
  6. {"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
  7. {"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
  8. {"sensors_data_close", "()I", (void*)sensors_data_close },
  9. {"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },

  10. };
复制代码

       下面的是一个简单的例子:

Java代码:
  1. sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo){
  2. jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
  3. jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
  4. int fd = env->GetIntField(fdo, offset);
  5. return sSensorDevice->data_open(sSensorDevice, fd);
  6. }
复制代码

        调用到最后其实都是用的 sSensorDevice 的方法   static sensors_data_device_t* sSensorDevice = 0;

       2.service 部分
  frameworks/base/services/jni/com_android_server_SensorService.cpp先看一眼它的方法注册

Java代码:
  1. static JNINativeMethod gMethods[] = {
  2. {"_sensors_control_init", "()I", (void*) android_init },
  3. {"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
  4. {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
  5. {"_sensors_control_wake", "()I", (void*) android_data_wake },
  6. {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
  7. };
复制代码

阅读(1385) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~