Android之传感器系统(Gsensor) .

最近在解关于Gsensor的Bug,Bug还没解掉,反而把Android的Gsensor流程走了一遍。好久不写博客了,不能偷懒啊,学了东西还是得总结一下,好让后来人不要费多少工夫,同时抛砖引玉,大家一起讨论一下,有什么错误我好纠正一下,对自己也是一种激励。言归正传,本文主要从上层的Activity一直分析到kernel的driver,路比较长,不过我喜欢搞清楚架构。

目录:

一、应用层的API;

二、Framwork中的处理;

三、C++中的JNI;

四、Kernel的Gsensor-driver;

 

一、应用层的API

 

先看一个例子,这个例子是Gsensor的最简单应用,只是用来打印x,y,z的三个值:

[java] view
plain
copy

  1. public class main extends Activity {    
  2.     private float x, y, z;    
  3.     protected void onCreate(Bundle savedInstanceState) {    
  4.         super.onCreate(savedInstanceState);   
  5.         SensorManager mSensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);   
  6.         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);  
  7.         SensorEventListener lsn = new SensorEventListener() {  
  8.   
  9.                     public void onSensorChanged(SensorEvent e) {  
  10.                             System.out.println(e.value[0]);  
  11.                             System.out.println(e.value[1]);  
  12.                             System.out.println(e.value[2]);  
  13.                      }  
  14.                     public void onAccuracyChanged(Sensor s, int accuracy) {  
  15.                     }      
  16.                };  
  17.                mSensorManager.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  
  18. }  

[java] view
plain
copy

  1. public class main extends Activity {    
  2.     private float x, y, z;    
  3.     protected void onCreate(Bundle savedInstanceState) {    
  4.         super.onCreate(savedInstanceState);   
  5.         SensorManager mSensorManager= (SensorManager) getSystemService(SENSOR_SERVICE);   
  6.         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);  
  7.         SensorEventListener lsn = new SensorEventListener() {  
  8.   
  9.                     public void onSensorChanged(SensorEvent e) {  
  10.                             System.out.println(e.value[0]);  
  11.                             System.out.println(e.value[1]);  
  12.                             System.out.println(e.value[2]);  
  13.                      }  
  14.                     public void onAccuracyChanged(Sensor s, int accuracy) {  
  15.                     }      
  16.                };  
  17.                mSensorManager.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);  
  18. }  

  

    这段代码中我们重点关注这几个类:SensorManager,SensorEvent;然后我们进入到Framework中看看这两个类是如何实现,它们都做了什么操作。

 

二、Framework中的处理

    相关文件:/frameworks/base/core/java/android/hardware/SensorManager.java;

    这个SensorManager主要负责返回传感器类型,从底层获得数据。getSystemService(String name)是根据名字返回相应的Manager,这个机制也比较重要,网上有相关资料,在此不展开讨论了;mSensorManager.getDefaultSensor(type)就是获取指定类型的传感器。这些类型在API手册中都能查到,包括温度传感器,重力感应器等。registerListener注册监听器,这是为了能让ManagerSensor回调正确的接口函数,注册的时候我们可以指定sensor的灵敏度,分四个等级,API手册中有相应介绍。我们来看一下SensorManager的构造函数:

     1.获取windowManager实例,监控屏幕旋转状态;

     2.初始化sensorList传感器列表;调用了sensors_module_init()和sensors_module_get_next_sensor()两个本地JNI方法;

     3.构造SensorThread线程(这里线程并没有开启);

      系统中只维护了一个SensorManager,应用层的调用只是往SensorManager里面注册了一个监听接口,然后使能相应的Sensor,设置Sensor的参数;SensorManager的获取是通过调用getSystemService方法,这个方法会检测SensorManager是否已经存在了,如果存在了一个实例就直接返回这个实例。

     下面重点分析一下SensorThread线程,这个线程的开启是在registerListener里面,SensorThread是一个死循环,他通过调用native方法sensors_data_poll方法来轮询下层发来的传感器数据。每次接受到一个数据就会调用代理listener中的onSensorChangedLocked方法,把它封装成一个消息发给自己的messagerHandler,在这里面最终调用注册的onSensorChanged方法,也就是我们上面应用程序接口的中方法。

 

 

三、C++中的JNI

     相关文件:/frameworks/base/core/jni/android_hardware_SensorManager.cpp;

     sensors_module_init()模块初始化-->hw_get_module()-->load(),其实就是把sensor.so的链接库加载进来;

     sensor.so是与机器相关的hardware层来实现的,要在hardware下实现相应的sensor.cpp;这个文件就是跟kernel打交道的最底层的文件了。里面主要完成了打开设备文件,读取设备节点的数据。比如我们的Gsensor是走的输入输出子系统,就打开相应的event文件来读取驱动上报的坐标数据。

    

    

 

四、Kernel中的驱动

     这个我们的实现比较简单,是走的input子系统。你可以选择用中断模式或者轮询模式来读取设备发来的数据。

 

五、SensorService(对比SensorManager)

     其实还有一个非常重要的类没有说,就是SensorService;现在有必要把整个Sensor总结分析一下了。

     系统开启之后会依次启动各种系统服务;源码在SystemServer.java中,在这里系统会new一个SensorService,SensorService中会调用JNI方法_sensors_control_init,对应com_android_server_SersorService.cpp中的android_init();这个主要是初始化SensorDevice的句柄供以后调用;下面是com_android_server_SersorService.cpp注册的JNI方法:

    

[java] view
plain
copy

  1. static JNINativeMethod gMethods[] = {  
  2.     {"_sensors_control_init",     "()I",   (void*) android_init },  
  3.     {"_sensors_control_open",     "()Landroid/os/Bundle;",  (void*) android_open },  
  4.     {"_sensors_control_close",     "()I",  (void*) android_close },  
  5.     {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },  
  6.     {"_sensors_control_wake",     "()I", (void*) android_data_wake },  
  7.     {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },  
  8. };  

[java] view
plain
copy

  1. static JNINativeMethod gMethods[] = {  
  2.     {"_sensors_control_init",     "()I",   (void*) android_init },  
  3.     {"_sensors_control_open",     "()Landroid/os/Bundle;",  (void*) android_open },  
  4.     {"_sensors_control_close",     "()I",  (void*) android_close },  
  5.     {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },  
  6.     {"_sensors_control_wake",     "()I", (void*) android_data_wake },  
  7.     {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },  
  8. };  

    从这里我们可以看出,SensorService这个类主要是负责控制Sensor设备的。这些JNI函数最终都会调用到我们Sensor.cpp里面的实现。对比我们的SensorManager中JNI的注册:

   

[java] view
plain
copy

  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",  
  5.                                             (void*)sensors_module_get_next_sensor },  
  6.     {"sensors_data_init", "()I",            (void*)sensors_data_init },  
  7.     {"sensors_data_uninit", "()I",          (void*)sensors_data_uninit },  
  8.     {"sensors_data_open",  "([Ljava/io/FileDescriptor;[I)I",  (void*)sensors_data_open },  
  9.     {"sensors_data_close", "()I",           (void*)sensors_data_close },  
  10.     {"sensors_data_poll",  "([F[I[J)I",     (void*)sensors_data_poll },  
  11. };  

[java] view
plain
copy

  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",  
  5.                                             (void*)sensors_module_get_next_sensor },  
  6.     {"sensors_data_init", "()I",            (void*)sensors_data_init },  
  7.     {"sensors_data_uninit", "()I",          (void*)sensors_data_uninit },  
  8.     {"sensors_data_open",  "([Ljava/io/FileDescriptor;[I)I",  (void*)sensors_data_open },  
  9.     {"sensors_data_close", "()I",           (void*)sensors_data_close },  
  10.     {"sensors_data_poll",  "([F[I[J)I",     (void*)sensors_data_poll },  
  11. };  

    不难看出,SensorManager主要负责的是数据的传输;

    OK,到这里Sensor基本就分析完了。其中WindowManager跟Sensor打交道,实现转屏等操作,这里就先不做分析了。本人水平有限,接触android也就两个月的时间,有什么不对或者欠妥的地方欢迎指正。 

时间: 2024-09-20 12:27:08

Android之传感器系统(Gsensor) .的相关文章

Android系统移植与调试之------->Android Sensor传感器系统架构初探

1. 体系结构 2. 数据结构 3. 四大函数 本文以重力感应器装置G-sensor为例探索Android的各层次结构. 1. 体系结构     Android的体系结构可分为4个层次. 第一层次  底层驱动层,包括标准Linux,Android核心驱动,Android相关设备驱动,G-sensor的设备驱动程序即存在于此 第二层次 Android标准C/C++库,包括硬件抽象层,Android各底层库,本地库,JNI 第三层次 Android Java Framwork框架层 第四层次 Jav

Android 系统Gsensor系统架构

一.首先建立这样一个全局的观念:     Android中sensor在Android系统架构中的位置及其工作.方框图如下: 从以上方框图中,可以看出Android中sensor在系统分为四层:驱动层(Sensor Driver).硬件抽象层(Native).中间层(Framework).应用层(Java).硬件抽象层与中间层可以合并一起作为Framework层. 针对我们xx这里一个具体的Gsensor,下面将以具体的源码形式来讲解以上的这个系统框图.   二.驱动层(Sensor Drive

首次调用一直运行-Android 加速度传感器 app手机调用会自己不断的运行

问题描述 Android 加速度传感器 app手机调用会自己不断的运行 app 首次调用系统传感器的时候,手机没有动,传感器会一直运行,过了30几秒才会停下来,目前只有在锁屏后传感器依旧可以运行的手机上发现这个问题,其它手机暂时没有.补充:在android中使用传感器相关类获取加速表的值后,发现值在不停的变,即使是将手机平放在桌面上值也不会固定,不知道是否是灵敏度的问题,想要利用加速表测算出手机移动的距离,如果加速表的值一直变,会有很大的误差,请高手指教.手机平放桌面时,获取的x轴和y轴的值不是

Android重力传感器实现滚动的弹球_Android

熟知: 什么是传感器:      所谓传感器能够探测如光.热.温度.重力.方向 等等的功能! Android中提供传感器有哪些:      1.  加速度传感器(重力传感器)      2.  陀螺仪传感器      3.  光传感器      5.  恒定磁场传感器      6.  方向传感器      7.  恒定的压力传感器      8.  接近传感器      9.  温度传感器 一. 问题描述 Android中有多达11种传感器,不同的手机设备支持的传感器类型也不尽相同 1. 重力

Android利用传感器仿微信摇一摇功能

传感器 简单的介绍一下传感器: 就是设备用来感知周边环境变化的硬件. Android中的传感器包含在传感器框架中,属于android.hardware.*(硬件部分) 传感器框架主要包含四个部分: ① SensorManager:用来获取传感器的入口,它是一个系统的服务,还可以为传感器注册与取消注册监听 ② Sensor: 具体的传感器,包含了传感器的名字,类型,采样率 ③ SensorEvent:传感器事件,包含了传感器采集回来的数据,传感器的精度 ④ SensorEventListener:

Android 4.3系统新功能:拍照界面更新

根据最近泄露的一份代码显示,最新的Android 4.3果冻豆系统将会支持应用和小部件根据使用频率次数排序,而不仅仅是目前默认采用的根据字母顺序排序.Myce网站首先在谷歌Chromebook Pixel的Google Launcher代码中发现了这一特殊的功能,而并不是在之前泄露版的Android 4.3测试系统中发现的新特性. 另外,根据一位内部人士透露,即将发布的Android 4.3系统也对核心的系统内置应用界面进行了更新.并且这位内部人士表示,Android 4.3将是所有版本系统中最

android如何获取系统剪贴板内容被加入的时间

问题描述 android如何获取系统剪贴板内容被加入的时间 我要利用android系统剪贴板做一些需求,需要设置一个剪贴板内容的失效时间,但是不知道如何获取剪贴板内容进入的系统时间.查API未果,求大神解答 解决方案 你可以自己另外保存时间. 解决方案二: 可以自己用sharedpreferenced保存时间

《深入解析Android 5.0系统》——第6章,第6.2节Android native层的同步方法

6.2 Android native层的同步方法 深入解析Android 5.0系统 Android在Linux提供的线程同步函数的基础上进行了二次封装,让实现线程同步更加简单方便.这些同步类和函数在native层的代码中出现的非常频繁. 6.2.1 互斥体Mutex和自动锁Autolock Mutex和Autolock是Android native层最常见的一种临界区保护手段,Autolock只是提供了一种更简便的使用Mutex的方法. Mutex是一个C++的类,它的接口如下所示: clas

Android群英传笔记——第一章:Android体系与系统架构

Android群英传笔记--第一章:Android体系与系统架构 图片都是摘抄自网络 今天确实挺忙的,不过把第一章的笔记做一下还是可以的,嘿嘿 1.1 Google的生态圈 还是得从Android的起源说起,Android是一个以Linux为基础的开源移动设备操作系统,主要用于智能手机和平板电脑,由Google成立的Open Handset Alliance(OHA,开放手持设备联盟)持续领导与开发中.Android已发布的最新版本为Android 6.0.1(M). Android系统最初由安