热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android之传感器系统

近在解关于Gsensor的Bug,Bug还没解掉,反而把Android的Gsensor流程走了一遍。好久不写博客了,不能偷懒啊࿰

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

目录:

一、应用层的API;

二、Framwork中的处理;

三、C++中的JNI;

四、Kernel的Gsensor-driver;

一、应用层的API

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

 

view plaincopy to clipboardprint?
  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方法:

    

view plaincopy to clipboardprint?
  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的注册:

   

view plaincopy to clipboardprint?
  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也就两个月的时间,有什么不对或者欠妥的地方欢迎指正。 




推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • Day2列表、字典、集合操作详解
    本文详细介绍了列表、字典、集合的操作方法,包括定义列表、访问列表元素、字符串操作、字典操作、集合操作、文件操作、字符编码与转码等内容。内容详实,适合初学者参考。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
author-avatar
王海937_264
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有