android中Sensor 工作流程
来源:互联网 发布:美的集团社会关系网络 编辑:程序博客网 时间:2024/05/16 08:49
转自http://www.apkbus.com/forum.php?mod=viewthread&tid=2740
我们使用 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
先看一眼它的方法注册
- static JNINativeMethod gMethods[] = {
- {"_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:pen_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.
- *
- * @return 0 if successful, < 0 on error
- */
- 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.
- *
- * @return 0 if successful, < 0 on error
- */
- 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) {
- return module->methods->open(module,
- SENSORS_HARDWARE_DATA, (struct hw_device_t**)device);
- }
- static inline int sensors_data_close(struct sensors_data_device_t* device) {
- return device->common.close(&device->common);
- }
- android中Sensor 工作流程
- android中Sensor 工作流程
- android中Sensor 工作流程
- android中Sensor 工作流程
- Android传感器Sensor工作流程
- Android中G-Sensor流程
- Android中G-Sensor流程
- Android 浅谈Sensor工作流程(一)
- Android 浅谈Sensor工作流程(二)
- Android Sensor工作流程(一)
- sensor工作流程
- Lighting sensor 工作流程
- Android中G-Sensor相关流程
- Android中G-Sensor相关流程
- Android中G-Sensor相关流程
- Android中G-Sensor相关流程 转
- Android中G-Sensor相关流程
- Android中G-Sensor相关流程
- PKU 概率论总结
- 1010 Tempter of the Bone 深度搜索 奇偶剪枝
- 好公司职位要求
- Cocos2d-x2.0 之 ClickAndMoveTest “谈不上深入”的分析.
- Android Sensor感应器介绍(一)重力感应加速度获取
- android中Sensor 工作流程
- Cocos2d-x2.0 RotateWorldTest深入分析
- [Android实例] Sensor传感器源码的阅读与应用开发简单实例
- Android 浅谈Sensor工作流程(一)
- 消失的子弹
- Android 浅谈Sensor工作流程(二)
- Android中G-Sensor相关流程
- Andriod Sensor HAL实现
- MATLAB 3D 动画制作(一)- 3D 图形设计