本文转载自:http://blog.csdn.net/mwj19890829/article/details/18751447html
关于Android定位方式前端
android 定位通常有四种方法,这四种方式分别是GPS定位、WIFI定位、基站定位、AGPS定位。java
一、 Android GPSlinux
须要GPS硬件支持直接和卫星交互来获取当前经纬度,这种方式须要手机支持GPS模块如今大部分的智能机应该都有了。经过GPS方式准确度是最高的可是它的缺点也很是明显。android
一、 比较耗电git
二、 绝大部分用户默认不开启GPS模块web
三、 从GPS模块启动到获取第一次定位数据可能须要比较长的时间算法
四、 室内几乎没法使用。后端
这其中缺点二、3都是比较致命的。须要指出的是GPS走的是卫星通讯的通道在没有网络链接的状况下也能用。数组
二、 Android基站定位
Android基站定位只要明白了基站/WIFI定位的原理本身实现基站/WIFI定位其实不难。基站定位通常有几种:第一种是利用手机附近的三个基站进行三角定位,因为每一个基站的位置是固定的,利用电磁波在这三个基站间中转所须要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站 id、location area code、mobile country code、mobile network code和信号强度将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息,偏差通常在几十米到几百米以内。其中信号强度这个数据很重要。
三、 Android Wifi定位
根据一个固定的Wifi MAC地址经过收集到的该Wifi热点的位置而后访问网络上的定位服务以得到经纬度坐标。由于它和基站定位其实都须要使用网络因此在Android也统称为Network方式。
四、 AGPS定位
AGPS(AssistedGPS)辅助全球卫星定位系统是结合GSM或GPRS与传统卫星定位利用基地台代送辅助卫星信息以缩减GPS芯片获取卫星信号的延迟时间受遮盖的室内也能借基地台讯号弥补减轻GPS芯片对卫星的依赖度。和纯GPS、基地台三角定位比较,AGPS能提供范围更广、更省电、速度更快的定位服务。理想偏差范围在10公尺之内,日本和美国都已经成熟运用AGPS于LBS服务(Location Based Service)基于位置的服务。AGPS技术是一种结合了网络基站信息和GPS信息对移动台进行定位的技术,能够在GSM/GPRS、WCDMA和CDMA2000网络中进行使用。该技术须要在手机内增长GPS接收机模块并改造手机的天线,同时要在移动网络上加建位置服务器、差分GPS基准站等设备。AGPS解决方案的优点主要体如今其定位精度上在室外等空旷地区其精度在正常的GPS工做环境下能够达到10米左右,堪称目前定位精度最高的一种定位技术。该技术的另外一优势为首次捕获GPS信号的时间通常仅需几秒,不像GPS的首次捕获时间可能要2-3分钟。
关于android上的gps定位
关于gps定位,从卫星信号到android终端地图显示的总体流程图以下:
如下简单介绍下GPS定位的相关知识
1、GPS简介
GPS(Global Positioning System), 即全球定位系统,它是一个由覆盖全球的24颗卫星组成的卫星系统。其目的是在全球范围内对地面和空中目标进行准肯定位和监测。随着全球性空间定位信息应用的日益普遍,GPS提供的全时域、全天候、高精度定位服务将给空间技术、地球物理、大地测绘、遥感技术、交通调度、军事做战以及人们的平常生活带来巨大的变化和深远的影响。
目前的民用GPS设备包括测量型和导航型。其中测量型产品的精度可达到米级甚至毫米级,但至少须要两台(套)才能达到设计精度要求,并且其内部结构复杂,单机成本通常在几万到几十万,适合专业高精度测量环境使用;导航型产品,因为其使用者对精度要求不高,通常为几十米,所以机器内部硬件相对简单,只须一台就能够完成导航工做,加之其价格相对较低,于是更有普及和推广价值。
GPS系统通常由地面控制站、导航卫星和用户接收机(GPS的移动用户端)三大部分组成。导航卫星至少24颗,均匀分布在6个极地轨道上,轨道的夹角为60度,距地平均高度为20200千米,每12恒星时绕地球一周。
2、GPS卫星信号结构
GPS卫星发射的信号包含有三种成分,即50Hz导航电文(D码)、伪随机码(C/A码或P码)和载波(Ll,L2波段)。这3种信号份量都是在同一基准频率F0=10.23MHZ的控制下产生的。
GPS卫星信号结构
GPS卫星所采用的两种测距码,即C/A码和P码(或Y码),均属于伪随机码。
1)C/A码:是由两个10级反馈移位寄存器组合而产生。码长Nu=1024-1=1023比特,码元宽为tu=1/f1=0.97752s,(f1为基准频率f0的10分之1,1.023 MHz),相应的距离为293.1m。周期为Tu= Nutu=1ms,数码率为1.023Mbit/s。
C/A码的码长短,共1023个码元,若以每秒50码元的速度搜索,只需20.5s,易于捕获,称捕获码。
码元宽度大,假设两序列的码元对齐偏差为为码元宽度的1/100,则相应的测距偏差为2.9m。因为精度低,又称粗码。
2)P码
P码产生的原理与C/A码类似,但更复杂。发生电路采用的是两组各由12级反馈移位寄存器构成。码长Nu=2.35*10^14比特,码元宽为tu=1/f0=0.097752s,相应的距离为29.3m。周期为Tu= Nutu=267d,数码率为10.23Mbit/s。
P码的周期长,267天重复一次,实际应用时P码的周期被分红38部分,(每一部分为7天,码长约6.19 ,1012比特),其中1部分闲置,5部分给地面监控站使用,32部分分配给不一样卫星,每颗卫星使用P码的不一样部分,都具备相同的码长和周期,但结构不一样。P码的捕获通常是先捕获C/A码,再根据导航电文信息,捕获P码。因为P码的码元宽度为C/A码的1/10,若取码元对齐精度仍为码元宽度的1/100,则相应的距离偏差为0.29m,故P码称为精码。
导航电文是包含有关卫星的参考星历、卫星工做状态、时间改正参数、卫星钟运行状态、轨道摄动改正、大气折射改正和由C/A码捕获P码等导航信息的数据码(或D码)。
导航电文也是二进制码,依规定格式组成,按帧向外播送。每帧电文含有1500比特,播送速度50bit/s,每帧播送时间30s。
每帧导航电文含5个子帧,每一个子帧分别含有10个字,每一个字30比特,故每一个子帧共300比特,播发时间6s。为记载多达25颗卫星,子帧四、5各含有25页。子帧一、二、3和子帧四、5的每一页构成一个主帧。主帧中一、二、3的内容每小时更新一次,四、5的内容仅当给卫星注入新的导航电文后才得以更新。
导航电文的格式:
一帧导航电文的内容
一、 遥测字(TLM-Telemetry WORD)
位于每一个子帧的开头,做为捕获导航电文的前导。
二、转换码(交接字)(HOW-Hand Over Word)
紧接各子帧的遥测字,主要向用户提供用于捕获P码的Z记数。所谓Z记数是从每一个星期六/星期日子夜零时起算的时间记数(1.5s),代表下一子帧开始瞬间的GPS时。
三、数据块1:含有卫星钟改正参数及数据龄期、星期的周数编号、电离层改正参数、和卫星工做状态等信息。 卫星钟改正参数a0、a一、a2分别表示该卫星的钟差、钟速和钟速变化率。任意时刻t的钟改正数为:
t=a0+a1(t-t0c)+a2(t-t0c)^2。
参考历元t0e为数据块1的基准时间,从GPS时星期六/星期日子夜零时起算,变化于0-604800s之间。
数据龄期AODC表示卫星钟改正参数的参考时刻t0c与最近一次更新钟改正参数的时间TL之差,主要用于评价钟改正数的可信程度。
现时星期编号WN:表示从1980年1月6日协调时零点起算的GPS时星期数。
四、数据块2:包含在二、3两个子帧里,主要向用户提供有关计算该卫星运行位置的信息。该数据通常称为卫星星历,每30s重复1次,每小时更新一次。
五、数据块3:包含在四、5两个子帧中,主要向用户提供其余GPS卫星的概略星历及其工做状态信息,称为卫星的历书。第3数据块的内容每12.5分钟重复一次,天天更新一次。
3、GPS接收机
天线单元
GPS信号接收机的天线单元为接收设备的前置部分。天线单元包含接收天线和前置放大器两部分。
其中天线部分多是全向振子天线或小型螺旋天线或微带天线,但从发展趋势来看,以微带天线用的最广、最有前途。
为了提升信号强度,通常在天线后端设置前置放大器,前置放大器的做用是将由极微弱的GPS信号的电磁波能量转换成为弱电流放大。前置放大器分外差式和高放式两种。因为外差式前置放大器不只具备放大功能,还具备变频功能,即将高频的GPS信号变换成中频信号,这有利于得到稳定的定位精度,因此绝大多数GPS接收机采用外差式天线单元。
信号通道
信号通道是一种软件和硬件相结合的复杂电子装置,是GPS接收机中的核心部分。其主要功能是捕获、跟踪、处理和量测卫星信号,以得到导航定位所须要的数据和信息。通道数目有1到24个不等,由接收机的类型而定。总的来说,信号通道目前有相关型、平方型和相位型等三种。新一代GPS信号接收机普遍采用相关型通道,主要由信号捕获电路、伪噪声跟踪环路和载波跟踪环路组成。
存储器
这是GPS信号中接收机将定位现场采集的伪距、载波相位测量、人工量测的数据及解译的卫星星历储存起来的一种装置,以供差分导航和做相对定位的测后数据。
微处理机
接收机的计算部分由微处理机和机内软件组成。机内软件是由接收机生产厂家提供的,是实现数据采集、通道自校自动化的重要组成部分,主要用于信号捕获、跟踪和定位计算。微处理机结合机内软件做下列计算和处理:
(1)开机后指令各通道自检,并测定、校订和存储各通道的时延值;
(2)解译卫星星历,计算测站的三维坐标;
(3)由测站定位坐标和卫星星历计算全部卫星的升降时间、方位和高度角,提供可视卫星数据及卫星的工做情况,以便得到最佳定位星位,提升定位精度。
定位
静态定位时,GPS接收机在捕获和跟踪GPS卫星的过程当中固定不变,接收机经过高精度测量GPS信号的传播时间,并利用GPS卫星在轨的已知位置解算出接收机天线所在位置的三维坐标。而动态定位则是用GPS接收机测定一个运动物体的运行轨迹。GPS信号接收机所在的运动物体叫作载体(如航行中的船舰,空中的飞机,行走的车辆等)。因为载体上的GPS接收机天线在跟踪GPS卫星的过程当中将相对地球而运动,这样,接收机用GPS信号就可实时地测量运动载体的状态参数(瞬间三维位置和三维速度)。
GPS定位还受GPS网的限制,应用GPS卫星定位技术创建的控制网叫GPS网。概括起来大体可分为两大类:一类是全球或全国性的高精度GPS网,这类GPS网中相邻点的距离在数千千米至上万千米, 其主要任务是做为全球高精度坐标框架或全国高精度坐标框架,觉得全球性地球动力学和空间科学方面的科学研究工做服务。另外一类是区域性的 GPS网,包括城市或矿区GPS网,GPS工程网等,这类网中的相邻点间的距离为几千米至几十千米,其主要任务是直接为国民经济建设服务。
二维位置的肯定
由卫星产生的测距信号肯定三维位置
GPS接收机常识:
1. 坐标 (coordinate)
有2维、3维两种坐标表示,当GPS可以收到4颗及以上卫星的信号时,它能计算出本地的3维坐标:经度、纬度、高度,若只能收到3颗卫星的信号,它只能计算出2维坐标:经度和纬度,这时它可能还会显示高度数据,但这数据是无效的。大部分GPS不只能以经/纬度(Lat/Long) 的方式,显示坐标,并且还能够用 UTM(Universal TransverseMercator) 等坐标系统显示坐标但咱们通常仍是使用 LAT/LONG 系统,这主要是由你所使用的地图的坐标系统决定的。
2. 航点 (Landmark or Waypoint)
GPS内存中保存的一个点的坐标值。在有GPS信号时,你能够存储成一个易认的名字,还能够给它选定一个图标。航点是GPS数据核心,它是构成“航线”的基础。标记航点是GPS主要功能之一,可是你也能够从地图上读出一个地点的坐标,手工或经过计算机接口输入GPS,成为一个航点。一个航点能够未来用于GOTO功能的目标,也能够选进一条航线 Route,做为一个支点。通常 GPS 能记录500个或以上的航点。
3. 航线 (ROUTE)
航线是GPS内存中存储的一组数据,包括一个起点和一个终点的坐标,还能够包括若干中间点的坐标,每两个坐标点之间的线段叫一条"腿"(leg) 。常见 GPS 能存储20条线路,每条线路30条"腿"。各坐标点能够从现有航点中选择,或是手工/计算机输入数值,输入的路点同时作为一个航点 (Waypoint/Landmark) 保存。
4. 前进方向 (Heading)
GPS没有指北针的功能,静止不动时它是不知道方向的。可是一旦动了起来,它就能知道本身的运动方向。GPS每隔一秒更新一次当前地点信息,每一点的坐标和上一点的坐标一比较,就能够知道前进的方向 。
5. 导向 (Bearing)
导向功能在如下条件下起做用:
1.) 以设定"走向"(GOTO) 目标。"走向"目标的设定能够按"GOTO"键,而后从列表中选择一个航点。之后"导向"功能将导向此航点
2.) 目前有活跃航线 (Activity route)。活跃航线通常在设置 -> 航线菜单下设定。若是目前有活动航线,那么"导向"的点是航线中第一个路点,每到达一个路点后,自动指到下一个路点。
6. 日出日落时间 (Sun set/raise time)
大多数GPS可以显示当地的日出、日落时间,这在计划出发 / 宿营时间时是有用的。这个时间是 GPS 根据当地经度和日期计算获得的,是指平原地区的日出、日落时间,在山区由于有山脊遮挡,日照时间根据状况要迟早各少半个小时以上。GPS的时间是从卫星信号获得的格林尼制时间,在设置 (setup) 菜单里能够设置本地的时间偏移,对中国来讲,应设+8小时,此值只与时间的显示有关。
7. 航迹 (Plot trail)
GPS每秒更新一次坐标信息,因此能够记载本身的运动轨迹。通常GPS能记录1024个以上足迹点,在一个专用页面上,以可调比例尺显示移动轨迹。足迹点的采样有自动和定时两种方式自动采样由 GPS 自动决定足迹点的采样方式,通常是只记录方向转折点,长距离直线行走时不记点;定时采样能够规定采样时间间隔,好比30秒、一分钟、 5 分钟或其余时间,每隔这么长时间记一个足迹点。
4、主流GPS方案供应商
一台GPS设备关键的元件有天线、低噪音放大器(LNA)、射频接收转换(RF Section)、数字部分(也称数字基带,Digital Baseband)、微处理器(Microprocessor)、微处理器周边外设(Processor Peripherals)、输入输出和驱动(I/OandDriver)等几个部分。芯片提供商也强手如云,包括 SiRF、u-blox、Ti、Analog Devices、NXP、高通、英飞凌、索尼、意法半导体、Trimble(天宝)、Atmel、SiGe、u-Nav 等等。
一、SiRF公司
SiRF是GPS芯片的龙头供应商,产品线完整,可以提供完整的解决方案。
表明产品:基于SiRFstarIII 架构的芯片GSC3e/LP与GSC3f/LP、GSC3LT与 GSC3LTf、GSC3LTi and GSC3Ltif,基于 SiRF Instant 架构的 GSCi-5000。现最新的模块为Fastrax iT430,它是基于SiRFstar IV芯片和SiRFaware软件技术的GPS模块。
尺寸:9.6 x 9.6 x 1.85 mm
NemeriX 提供的产品包括模拟射频接收器和数字基带处理器。
Nemerix NB1042GPS 接收器模块,世界上功耗最低的GPS芯片组。
三、TI
TI的辅助GPS (A-GPS)解决方案在异步和同步蜂窝式网络内提供快速而精确的定位服务。这些解决方案在优化以后,适用于全部当前和发展中的无线标准(如 GSM、GPRS、EDGE、CDMA、UMTS 和 WCDMA)。 TI 在 2005 年推出的 90nm 工艺技术的单芯片 A-GPS 解决方案,GPS5300NaviLink 4.0单芯片采用 TI DRP技术,可实现离散的GPS解决方案。
四、Atmel
Atmel 的低功耗 GPS 模块芯片组高度集成并能极大节省制版空间。
Atmel与Magellan推出新的GPS芯片组ATR0663,包括一个先进的 GPS 基带和一个具有集成 2D 图形加速器的 LCD 控制器(以实现 2048 x 2048像素的虚拟屏幕支持)、一个 AC97 音频控制器,以及一个图像传感器接口。多种输入/输出 (I/O) 选项,包括以太网 (Ethernet)、USB 2.0 Full Speed Hostand Device、SD/MMC、TWI 和 USART,为PND应用提供了一个高针对性的片上系统 (SoC) 解决方案。
五、意法半导体
ST 也可以提供面向 GPS 应用的全系列解决方案,适用于车载与便携式导航系统。最新一代的 ST 导航/信息娱乐平台名为 NaviFlex,其集成度更高:融合 GPS 接收器和 Nomadik 应用处理器,保证了汽车多媒体应用无与伦比的音频、视频和成像质量。
六、Maxim
Maxim 公司可以提供低噪声、低功耗的GPS前端接收器和独特的GPS方案。
七、NXP
恩智浦半导体 (NXP Semiconductors,原飞利浦半导体),恩智浦的解决方案成功地将高质量导航功能与丰富的多媒体处理结合在一块儿,包括 MP3 播放、标准的以及高清晰的视频播放及录制、调频收音机、图像存储和游戏等。
八、英飞凌
Infineon和Global Locate合做推出的Hammerhead是全球首款单芯片CMOS GPS 接收器。该芯片支持移动站辅助式(MS-A)、移动站基于式(MS-B)、自主式和加强式跟踪模式。一流的室内信号跟踪效果,彻底支持辅助式和自主式跟踪模式,即便在最微弱的信号环境中也能够进行高度精确的导航。Hammerhead 芯片的基于主机的软件架构,不只将器件尺寸和成本减至最小,还容许将协议消息直接嵌入到 GPS 导航软件中。
九、U-Blox
来自瑞士的GPS技术公司u-blox AG公司以往主要提供命名为 TIM的GPS 模块,其中采用的SiRF公司GPS芯片。如今u-blox 也开始注重核心芯片的开发。新推出的 u-blox 5 系列全球定位系统以及随时可用的伽利略系统单芯片和芯片组拥有不到一秒的接收性能。这种新的芯片还拥有 SuperSense-160 dBm 探测和跟踪灵敏度、小于 50mW 的功率需求以及一个小于 100 平方毫米的覆盖区,适用于掌上电脑(PDA)、我的导航设备、照相机、手机、媒体播放器和其它电池操做便携式设备。
十、高通
目前,全球已有总计超过两亿部手机装备了高通公司的gpsOne辅助型GPS 技术。gpsOne 技术支持一系列极具吸引力的位置服务,其中包括各类各样针对消费者、商务和我的安全的应用。
5、GPS标准格式数据
模块输出信息主要包括4个部分:
一、GPS定位信息GPGGA(Global Positioning SystemFix Data)
二、当前卫星信息GPGSA(GPS DOP and ActiveSatellites)
三、可见卫星信息GPGSV(GPS Satellites in View)
四、推荐最小定位信息GPRMC(Recommended MinimumSpecific GPS/TRANSIT Data)
6、Linux driver层
UART接口,与gps模块通讯,即读取gps的信息。
7、android GPS hal层
由于linux底层驱动只须要有uart接口就能够接收到gps数据了,而android的hal层会调用linux内核层的uart驱动,因此,这里uart驱动就再也不分析了,只要hal层打开串口,而后read就能够了,这里我参考的是模拟器的gps。
本身新建的文件夹,用来适配gps:
hardware/libhardware_legacy/gps
gps头文件:
hardware/libhardware_legacy/include/hardware_legacy/gps.h
首先看一下GpsLocation这个结构体。
全部咱们要知道的数据都在这里了:经度、纬度、海拔、速度、精确度、世界标准时间等。而上层也只是须要这个数据结构,因此只要把这个数据结构给android上层,那么就OK了。
下面仍是主要分析下android模拟器是如何实现的。先看下简单的流程图:
首先看下hw主要结构体,gps是注册为hw模块的。编译后是生成gps.*.so的,而他的方法是调用gps_module_methods。
再看看open_gps作了什么,初始化了不少函数指针,具体含义能够看
而后再看看各个函数,这些函数是jni层会调用到的,这里简单介绍初始化、数据上报等操做。
首先是初始化函数qemu_gps_init,这里调用了gps_state_init函数,而后在这里打开咱们要的串口驱动设备,开启读取gps数据的线程。
当线程启动之后,那么就会在这个线程中处理一些事情了,接着看下gps_state_thread函数。
这里会把callback函数给设置好,用以传数据给jni层。
串口读取gps的数据ret = read( fd, buff, sizeof(buff) );
解析数据 nmea_reader_addc(reader, buff[nn] );
而后他会调用nmea_reader_parse(r );函数
这个函数会根据不一样的gps协议格式来分别处理。
if ( !memcmp(tok.p, "GGA", 3) )
这里会根据GGA的格式来处理,好比:
更新时间nmea_reader_update_time(r, tok_time);
更新经纬度nmea_reader_update_latlong
更新海拔nmea_reader_update_altitude
其余的依次都差很少。具体能够看源码。
最后处理完了之后,把便要把数据给jni层了。经过r->callback( &r->fix );这个callback函数,就是数据传输的主要函数了。
8、android GPS的JNI层
先仍是看下jni层的主要流程吧:分为一、Java到jni到hal和二、hal到jni到java。
GPS的jni的代码是在下面这个目录下的:
在com_android_server_location_GpsLocationProvider.cpp文件中,实现JNI方法。注意文件的命令方法,com_android_server_location前缀表示的是包名,表示硬件服务GpsLocationProvider是放在frameworks/base/services/java目录的com/android/server/location目录下的,即存在一个命令为
com.android.server.location.GpsLocationProvider的类。
在同一个目录下有一个onload.cpp,这个会注册这个jni而且调用register_android_server_location_GpsLocationProvider来实现java层到hal层的接口的调用。
在android_location_GpsLocationProvider_init函数中,经过Android硬件抽象层提供的hw_get_module方法来加载模块ID为GPS_HARDWARE_MODULE_ID的硬件抽象层模块,其中,GPS_HARDWARE_MODULE_ID是在<hardware/gps.h>中定义的。Android硬件抽象层会根据GPS_HARDWARE_MODULE_ID的值在Android系统的/system/lib/hw目录中找到相应的模块,而后加载起来,而且返回hw_module_t接口给调用者使用。在jniRegisterNativeMethods函数中,第二个参数的值必须对应GpsLocationProvider所在的包的路径,即com/android/server/location/GpsLocationProvider。
下面分步来看下,jni是如何工做的。
首先是onload.cpp这里会调用到
com_android_server_location_GpsLocationProvider.cpp的注册函数
register_android_server_location_GpsLocationProvider,而这个注册函数就注册了应用层的GpsLocationProvider的jni。他会调用下面这个注册函数。具体各个参数含义,第一个是env,是jni技术的主要结构体JNIEnv,第二个参数就是所要注册的java服务程序的包。最后一个是native方法的回调函数了。
下面的是native方法的一些函数。
对于这个method作一些简单的解释吧:。
第一个参数name是在java服务层定义的native函数。具体能够看
frameworks/base/location/java/com/android/server/location/GpsLocationProvide.java下的代码。
这个稍后分析。
第二个参数signature是java服务层调用jni层的参数,具体的能够先看下面这个表:
数组则以"["开始,用两个字符表示
实际上这些字符是与函数的参数类型一一对应的。
"()"中的字符表示参数,后面的则表明返回值。例如"()V" 就表示void Func();
"(II)V"表示 void Func(int, int);
上面的都是基本类型。若是Java函数的参数是class,则以"L"开头,以";"结尾中间是用"/" 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring
若是JAVA函数位于一个嵌入类,则用$做为类名间的分隔符。
例如"(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"
由此,上面写函数的参数也知道了。
第三个变量fnPtr是函数指针,指向C函数,也就是在jni的cpp代码中的。
而jni和java代码的交互能够看下图所示:
其实,java层和jni层都是能够互相调用的,而具体的java层调用jni的方法就是native声明的方法;jni调用java的话,要先获取java层的方法id,而后经过CallVoidMethod()等回调函数实现。
有了以上的知识点做为基础的话,那么如今来分析下GPS的jni代码了。
一、首先是android_location_GpsLocationProvider_class_init_native这个函数了。
他先是获取全部的方法id。而后调用hw模块,也就是上面hal层编译的gps.*.so连接库
而后调用了hal层的gps的open函数了。
获取接口sGpsInterface =gps_device->get_gps_interface(gps_device);
由于是gps不是agps因此
二、接着即是android_location_GpsLocationProvider_init这个初始化函数了。
该函数主要是调用了
这个函数的函数指针init就调用到hal层的init函数。也就是qemu_gps_init函数了。
这里传进来了callback函数了。
具体以下:
具体函数能够看下面:
这里会调用method_reportLocation这个方法,这个方法是在java服务层调用的。这里经过CallVoidMethod函数调用了Java framework的函数。
三、其余函数,开启导航,关闭导航等的就不一一介绍了,和上面的相似。能够看源码。
好了,jni层就大概分析好了,那么接着就是framework层的代码了。
9、android GPS的framework层
首先仍是主要流程图吧:
Framework层主要就是为上层应用调用提供接口。而GPS的framework层,根据jni的代码咱们也能够知道就在下面这个目录下了。
frameworks/base/services/java/com/android/server/location/GpsLocationProvide.java
那么android framework是怎么开始往下调用jni的呢?仍是看代码吧。
首先是在frameworks/base/services/java/com/android/server/SystemServer.Java
对于这个系统服务,仍是要从android启动流程讲起,首先linux内核启动完了以后,会调用android的init程序,而后挂载文件最小系统,解析init.rc和init.*.rc等脚本,接着zygote,启动虚拟机,而后就是运行到了systemserver了,也就是上面那个SystemServer.Java函数,在这个函数中,先看下SystemServer 这个类,发现了有一个native的init1函数。
native public static void init1(String[]args);
这个函数是调用了jni层的函数的,能够看
frameworks/base/services/jni/com_android_server_SystemServer.cpp
首先是进入其main函数,
加载库,而后就是调用了jni层的init1函数。
其调用了system_init();函数,而在system_init函数中
他又回调了SystemServer.Java中的init2函数。
在init2函数中
建立了一个线程,最后他会调用到ServerThread的run方法。
在其run()方法中会启动不少服务,好比Account Manager、ContentManager、System Content Providers、Lights Service、BatteryService、Vibrator Service、Alarm Manager、InitWatchdog、Window Manager等等,咱们这里最主要的就是关注LocationManagerService。
这里new了一个LocationManagerService对象,而且添加了这个service。
而后finalLocationManagerService locationF = location;
当activity manager好了以后就调用了locationF.systemReady();函数了。
下面进LocationManagerService.java中的system函数。
这里建立了一个线程,而后线程启动了,接着他会调用run方法。也就是
在run方法中,他会初始化一些东东,也就是initialize();函数了。
这里主要看loadProviders();函数。
这里又会调用loadProvidersLocked(),而后是_loadProvidersLocked()函数。其中就会调用到咱们须要的gpsprovider了。
在new一个GpsLocationProvider的时候会开一个GpsLocationProviderThread的线程
而后启动了线程,在这里会初始化,而后主要仍是new了一个ProviderHandler的类。
这个类中
就会处理不少事情了。具体能够看上面的代码。
接着他调用了updateProvidersLocked();这个函数。
updateProviderListenersLocked(name,true);
而后就启动了gps服务了
接着咱们开始往GpsLocationProvide.java这里看
这里发送了一个ENABLE消息,而后就会调用到上面ProviderHandler的函数,handleEnable();
这里就会调用到了jni的native函数了。
而native的全部函数,在jni中咱们都已经分析过了。
接着即是
enable函数结束后,那即是
一样,他也发送了ENABLE_TRACKING的消息,接着调用
接着调用了startNavigating函数,
这里主要仍是设置position mode,而后启动了。
接下来,咱们看看,jni调用的一些callback函数在这里作了些什么。
首先就是reportLocation函数了。
这里对于jni层获取的数据,作了处理后,更新了location信息。
其中下面这些都是给应用层的接口。
Ok,那么framwork层就介绍到这里了。
10、android GPS的APP层
首先看流程:
接上面的framework层,这里调用了mLocation是new了一个Location的类,这个类主要是给应用层接口的。
其代码在frameworks/base/location/java/android/location/Location.java
取其中一部分的函数作下简单的介绍。
mLocation.setLatitude(latitude);函数就会把
mLatitude= latitude;
而后,应用层只要getLatitude()就知道了纬度了。
其余的函数接口相似。
简单看下下面的一段应用层的代码
功能:展现GPS信息
终于,从卫星信号到android APP层获取到数据那个简单的数据流程分析好了。要想更加细致的了解其机制,仍是得须要花更多的时间继续深刻下去的。其中还有不少的细节,不少概念都不是很明白。只知道个大概。不过经过此次分析,收获很多。凡事都须要从总体到部分再到整理,从整理的GPS框架,到分红不少块理解,再把那些模块整合在一块儿,从而了解其整个机制。