第十八期 Android GPS原理分析《手机就是开发板》

https://blog.csdn.net/aggresss/article/details/54318662

如果想对Android的整个框架有一个更深层次的感性认识,我们还需要抓住一个点去研究一下。Android按照模块分成很多个系统,比如Audio,Video Out,Camera,Phone,WIFI,Blue Tooth,Light,Battery,Input,Codec,3D accelerator,Vibrator,Sensor,Alarm,Gps。
分析了一下这些模块,发现GPS模块是相对简单的一个模块,比较适合拿来做初学的分析,这一期我们就来分析一下Android中GPS的工作原理,然后我们做几个和GPS相关的实验。
GPS(Global Positioning System), 即全球定位系统,它是一个由覆盖全球的24颗卫星组成的卫星系统。其目的是在全球范围内对地面和空中目标进行准确定位和监测。随着全球性空间定位信息应用的日益广泛,GPS提供的全时域、全天候、高精度定位服务将给空间技术、地球物理、大地测绘、遥感技术、交通调度、军事作战以及人们的日常生活带来巨大的变化和深远的影响。
我们手机中内置的是一个GPS信号接收机,通过接收卫星产生的测距信号确定三维位置。从设备驱动的角度来看GPS接收机,就相当于一个定时输出的UART,所以从驱动的角度来讲想对简单,可以看做一个只有输出没有输出的驱动就好了。它的输出格式为NMEA 0183。
NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association )为海用电子设备制定的标准格式。目前业已成了GPS导航设备统一的RTCM(Radio Technical Commission for Maritime services)标准协议。

NMEA-0183数据实例1如下:
$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43
$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45


驱动程序通过解析NMEA数据可以分析出当前的坐标信息,移动信息和卫星信息,然后通过Android的结构框架逐层上报,最后我们的APP就能获得当前的位置信息。
下面这张图列出了在Android系统中GPS系统是怎么实现的:

整个定位服务的架构结构共分为四层:
最上面是应用层,即 android.location 包中包含的内容,是以 Java 语言提供的 API。
第二层是框架层,这一层包含了系统服务的实现,主要由 Java 语言来实现。
第三层是共享库层,本层由 C 以及 C++ 语言实现 , 框架层与共享库层使用 JNI 进行衔接。
最下面一层是 Linux 内核层 , 整个 Android 系统都是以 Linux 内核为基础的。
从上至下它们是逐层依赖的关系,每层依赖下面一层完成其所需提供的服务。
下面就要每个层次的开始分析,这里推荐几篇大神写的文章,讲得非常详细:
和菜鸟一起学android4.0.3源码之硬件gps简单移植
http://www.cnblogs.com/LiaoHao/p/3298511.html
Android 系统中 Location Service 的实现与架构
http://www.ibm.com/developerworks/cn/opensource/os-cn-android-location/
看完上面的两篇文章后我们来总结一下,当硬件接受到位置更新之后,为了通知这个信息,整个调用关系是如何的 ( 为了描述方便,下文将 com_android_server_location_GpsLocationProvider.cpp 简称为 GpsLocationProvider.cpp)。
当硬件检测到有位置更新之后,最初调用的是 GpsLocationProvider.cpp 中的 location_callback 函数。
location_callback 函数中对应的是调用 GpsLocationProvider.java 中的 reportLocation 方法。
GpsLocationProvider.java 中的 reportLocation 方法会调用 ILocationManager 的 reportLocation 方法,然后是调用 LocationManagerService 的 reportLocation 方法。
LocationManagerService 的 reportLocation 方法中会对 LocationWorkerHandler 发送消息 MESSAGE_LOCATION_CHANGED。该消息在 LocationWorkerHandler 的 handleMessage 方法中被处理。处理方法中会调用 LocationProviderInterface 的 updateLocation 方法和 LocationManagerService 的 handleLocationChangedLocked 的方法。前者对于 Gps 模块来说就是调用 GpsLocationProvider 的 updateLocation 方法。
GpsLocationProvider 的 updateLocation 方法会对 ProviderHandler 发送消息 UPDATE_LOCATION,该消息在 ProviderHandler 的 handler 方法中被处理,处理的方法是调用 handleUpdateLocation 方法,该方法中会调用 native_inject_location 方法以注入。
而 LocationManagerService 的 handleLocationChangedLocked 的方法会将最新的位置存放到 mLastKnownLocation 中。至此,便可以通过 LocationManagerService 的 getLastKnownLocation 方法获取到最新更新的位置信息了。

定位服务实现中牵涉到的文件一览

猜你喜欢

转载自blog.csdn.net/wxh0000mm/article/details/86302255
今日推荐