sensor app获取

如下表,如需要获取sensor,就需要获取相关的type,这里先给大家罗列一下

那么在ap中我们是如何使用数据的呢?

  1. 导入 android.hardware 包
  2. 实现 SensorEventListener 接口
  3. 使用的步骤:
    获取SensorManager:
    getSystemService(SENSOR_SERVICE)
    获取传感器:
    SensorManager.getDefaultSensor()
    注册传感器:
    SensorManager.registerListener()
    使用完后取消注册:
    SensorManager.unregisterListener();

拿一个简单获取accelerometer sensor举例如下:

public class SensorActivity extends Activity, implements SensorEventListener {     private final SensorManager mSensorManager;     private final Sensor mAccelerometer;     public SensorActivity() {         mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);         mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);     }     protected void onResume() {         super.onResume();         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);     }     protected void onPause() {         super.onPause();         mSensorManager.unregisterListener(this);     }     public void onAccuracyChanged(Sensor sensor, int accuracy) {}     public void onSensorChanged(SensorEvent event) {} }

这里我们能很清晰地看到整个sensor监听的过程,那么sensor在这里仅仅是去拿到的sensorManager,然后对这个sensormanger进行操作,那么对于AP来讲的话,只有Manager是可见的。

sensor的manger机制

根据sensor的AP与framerwork,我大致又可以为整个sensor自ap向下分为:

在使用sensor服务前,需要先获取sensorManager,

为何要有这样的架构

由于服务进程和应用运行在不同的进程,应用必须和服务建立进程间通信,这就为应用开发增加了许多繁琐的细节,为此, 引进Manager机制达到了暴露服务接口同时又隐藏共享服务的目的。

这样的做法有助于applications层的开发人员更加方便地进行开发

sensor Framework架构简介

在这里首先我先画出整个sensor的线路,有助于大家理解。

Android对Sensor HAL及其上层作出了定义,但是对于sensorHAL以下未作出定义,因而在kernel层却可以更加的随意,当然我在这里仍然是使用event dev的方式,通过input子系统向上发送数据(后面我又想开个专栏专门讲整个linux的子系统机制)。大家可以参考Android Sensor详解(4)driver的攻防战一文,看看我是如何写驱动的。

sensor的数据流向

在了解了sensor的大体流程后,那么我们可以联系ap层看看sensor又是如何去获取数据的。
于是画图如下:

当一个ap注册了传感器监听后,获取相关type的systemSensorManger,通过注册监听sensoreventqueue的数据变化,而这些变化又是由sensorService从sensor的hal层拿到的,而hal层通过input子系统,从kernel拿到了数据。
可以看到以下为sensor在hal层的event格式

typedef struct sensors_event_t {    int32_t version;    int32_t sensor;            //标识符    int32_t type;                //传感器类型    int32_t reserved0;    int64_t timestamp;        //时间戳    union {        float           data[16];        sensors_vec_t   acceleration;  //加速度        sensors_vec_t   magnetic;       //磁矢量        sensors_vec_t   orientation;     //方向        sensors_vec_t   gyro;               //陀螺仪        float           temperature;           //温度        float           distance;                 //距离        float           light;                        //光照        float           pressure;                 //压力        float           relative_humidity;    //相对湿度    };    uint32_t        reserved1[4];} sensors_event_t;

当然随着科技发展,现在的ic越来越强大,出现了light sensor/ p sensor等合集的IC,那么此时,lightsensor可能需要的不光光是lux了,在这里先卖个关子,后面在详解HAL层的时候再详细解释一下如何使用这个结构体

以下是各种类

  • SystemSensorManager:传感器框架中的java层Manager的实现者, 继承了java类 SensorManager
  • SensorManager: 特指native代码中的SensorManager类, 其提供了从SensorService获取传感器列表,建立连接通道的功能
  • SensorService:传感器框架中的 Service的实现者
  • SensorDevice:封装了Sensor HAL,并提供相应接口
  • SensorFusion:虚拟传感器的实现,根据所依赖的硬件传感器的值, 计算出虚拟传感器的值
  • SensorEventQueue,SensorEventConnnection:Service和Manager之间的连接而者之间具有层级关系

sensor框架初始化

大致上sensor的框架可以分为3个阶段
* sensorService实例化
* SensorManager初始化
* 建立Service与Manager之间的连接

sensorService实例化

  1. andorid启动到Init调用init.rc文件以service方式启动Zygote
  2. Zygoto会将启动android中所有应用程序及运行系统关键服务的system进程,它会创建一下虚拟机实力孵化新的进程,这里主要是启动了systemService
  3. SystemService用于管理系统的关键服务,它的main 方法中调用了init1(), 这是一个native 方法, 在其实现中, 间接调用了SensorService::instantiate()方法,导致了SensorService的实例化
  4. SensorService实现具体的方法如下图

SensorService启动后,通过defaultServiceManager::addService() 将自己添加到了系统服务管理中,然后等来自SensorManager的连接。

后续的SensorManager就可以使用defaultServiceManager:getService() 来获取 SensorService的实例来建立连接。
这就与前面讲到的ap串起来了。

SensorManager初始化

当在Ap中获取SensorManager的时候, 就会导致初始化流程进入第二个阶段。

setp1 获取SensorManager实例

初始化SensorManager时, java层的Manager(SystemSensorManager)在每个Context的实例注册时实例化一次,native层的Manager(SensorManager),在整个系统中只有唯一个一个实例

你通过同一个Context的实例只会获取到同一个SystemSensorService的实例

调用native_class_init

native_class_init 在native层实现,它仅仅只是将java层中Sensor 类的成员变量 的ID保存起来, 这样就可以在native代码中修改java中对象的值了。

保存的ID 后面将用于初始化java层的Sensor列表
在JNI机制中,native层无论是访问java层的变量还是方法,都需要先获取他们的ID值,然后再使用JNI机制提供的方法来调用方法或访问类对象的成员变量。

调用Sensor_module_init

Sensor_module_init()内部仅仅只是调用了
SensorManager::getInstance(),在系统中如果不存在Sensoranager的实例时,这将导致构造一个SensorManager对象

setp2 SensorManager初始化

mSensorList(0)调用

SensorManager的构造函数中将mSensorList初始化为空。

在HAL层中保存所有硬件上实现的传感器。

native层在HAL的基础上还会添加一些虚拟传感器。

java层保存的传感器列表在native层基础上有所删减

getService()调用

从defaultServiceManager处获取SensorService的指针,最多尝试4次

回想一下,SensorService在启动后将自己注册到defaultServiceManager现在,SensorManager直接找到组织,和SensorService接上头了。

这一过程将导致 SensorService的 OnFirstRef方法被调用,执行SensorService的初始化

获取的SensorService指针被保存在一个强引用对象中,自动强引用SensorService,调用SensorService的 OnFirstRef方法

setp3 SensorService初始化

调用SensorDevice:getInstance()

step4 SensorDevice初始化

调用hw_get_module/sensor_open/activate

调用hw_get_module加载Sensor模块的共享库文件(在system/lib64/)
调用sensors_open打开设备
调用activate 使能sensor模块

step5 SensorService初始化继续

调用getSensorList

通过SensorDevice.getSensorList向HAL层请求传感器列表并在Sensorervice中注册:
* 添加到mSensorList中去;
* 添加到sensorMap中去,传感器的Handle相关连;
* 新建一个传感器事件数据对象event 到mLastEventSeen中,和传感器的handle相关连

调用SensorFusion::getInstance实例化

SensorDevice封装了所有的 hardware sensor;SensorFusion则是封装了所有虚拟传感器,实现了它们的操作接口

调用registerVirtualSensor

虚拟传感器的注册过程和hardware sensor 的注册过程相同,在此基础上,还将其添加到了mVirtualSensorList中

  • 旋转矢量传感器
  • 重力传感器
  • 线性加速度传感器
  • 方向传感器
  • 真实的陀螺仪

step6 SensorService启动工作线程

调用run
SensorService的初始化已经完成, 现在,启动它的工作线程, 然后返回到调用它的SensorManager的构造函数中,继续执行。
SensorService进入工作线程循环后的细节, 等到整个Sensor framwork都初始化完毕

step7 SensorManger初始化

调用linkTodeath

注册一个到 SensorService的死亡监听器

SensorService异常退出时,sensorManager会自行死亡

通过systemService申请了某个service的Binder后,可以调用这个IBinder的linkToDeath函数注册一个Ibinder.DeathRecipient类型的对象。Ibinder.DeathRecipient是IBinder类中定义的一个嵌入类。当这个IBinder所对应的Service进程被异常的退出时,比如被kill掉,这时系统会调用这个Ibinder之前通过linkToDeath注册的DeathRecipient类对象的binderDied函数。

调用SensorService.getSensorList

又是获取传感器列表, 每一层都会从下层获取传感器列表并保存

step8 SystemSensorManager初始化

进一步调用Sensors_Module_get_next_sensor

回忆一下 native_class_init 中,将java层的Sensor类的成员变量保存在 native层SensorManager中。
这一步调用native层的 Sensor_module_get_next_sensor, 利用保存在SensorManager中的传感器列表来初始化SystemSensorManager 中的Sensor列表

new SensorThread

创建SystemSensorManager 的工作线程,负责从 native 层 的 SensorEventQueue 中读取传感器事件数据。

此时整个基础架构已经搭建完毕

好了,后面应该讲解如何建立连接了,但是时间关系,我在此便打住,会尽快将第二篇整理发出。

后言

我的想法是整个framework sensor部分分3大块解说,第一块是主体框架,第二块是源码分析,第三块是与HAL层的联系

敬请期待吧

更多相关文章

  1. android中度量坐标 传感器应用的开发
  2. Android 第三方库使用实例——编写.so库文件
  3. Android 拦截返回键事件的实例详解
  4. android中使用pull方式解析sdcard中的xml文件实例
  5. Netty多语言(Java、Android 、C#、WebSocket)通信实例Demo (一)概述
  6. Sensor传感器源码的阅读与应用开发简单实例
  7. Android中SharedPreference实例

随机推荐

  1. HBase调优 | HBase Compaction参数调优
  2. Cassandra排查 | 记一次Cassandra Java堆
  3. Zipkin服务端搭建使用教程
  4. 轻松开发3D可视化,构建数字孪生新世界Thin
  5. 科普NA公链(Nirvana):NAC公链采用基于NIO的N
  6. DolphinDB脚本语言的混合范式编程
  7. 如何避免ajax重复请求?
  8. HTML、HTML5重难点
  9. 数据调度组件:基于Azkaban协调时序任务执
  10. 7个最佳CSS优化技巧,可缩短页面加载时间