本文转载:http://blog.csdn.net/mwj19890829/article/details/18751447
android 定位一般有四种方法,分别是GPS定位、WIFI定位,基站定位,AGPS定位。
1、 Android GPS
需要GPS硬件支持直接与卫星互动以获得当前的经纬度,这需要手机支持GPS现在大多数模块应该有所有的智能机器。GPS方法精度最高,但缺点也很明显。
1、 比较耗电
2、 绝大多数用户默认不打开GPS模块
3、 从GPS从模块启动到获取第一定位数据可能需要很长时间
4、 室内几乎不可用。
缺点2、3都是致命的。需要指出的是,GPS卫星通信通道也可以在没有网络连接的情况下使用。
2、 Android基站定位
Android只要了解基站/基站定位WIFI定位原//WIFI定位并不难。一般有几种基站定位:第一种是使用手机附近的三个基站进行三角形定位,因为每个基站的位置是固定的,使用电磁波在三个基站之间计算手机的坐标;第二种是获取最近的基站信息,包括基站 id、location area code、mobile country code、mobile network code信号强度将这些数据发送到google的定位web在服务中,您可以获当前位置信息,误差一般在几十米到几百米之间。信号强度的数据非常重要。
3、 Android Wifi定位
根据固定Wifi MAC收集到的地址Wifi然后访问网络上的定位服务以获得经纬度坐标。因为它和基站定位实际上需要使用网络,所以在Android也统称为Network方式。
4、 AGPS定位
AGPS(AssistedGPS)辅助全球卫星定位系统GSM或GPRS与传统卫星定位利用基地台代送辅助卫星信息减少GPS芯片获取卫星信号的延迟时间也可以通过基地平台信号来弥补和减少GPS芯片对卫星的依赖。和纯GPS、基地台三角定位比较,AGPS可提供更广泛、更省电、更快的定位服务。理想误差范围在10公尺以内,日本和美国已成熟应用AGPS于LBS服务(Location Based Service)基于位置的服务。AGPS技术是网络基站信息的结合GPS在移动平台上定位信息的技术GSM/GPRS、WCDMA和CDMA使用2000网络。该技术需要在手机上增加GPS接收机模块,改造手机天线,在移动网络上增加位置服务器和差异GPS基准站等设备。AGPS解决方案的优势主要体现在室外等空旷地区的定位精度上其精度在正常的GPS工作环境可达10米左右,是目前定位精度最高的定位技术。该技术的另一个优点是第一次捕获GPS信号通常只需要几秒钟,不像GPS第一次捕获可能需要2-3分钟。
关于gps从卫星信号到定位android终端地图显示的整体流程图如下:
下面简单介绍一下GPS定位相关知识
GPS(Global Positioning System), 即,它是一个由覆盖世界的24颗卫星组成的卫星系统。其目的是准确定位和监控全球地面和空气目标。随着全球空间定位信息的广泛应用,GPS全职、全天候、高精度定位服务将给空间技术、地球物理、地球测绘、遥感技术、交通调度、军事作战和人们的日常生活带来巨大的变化和深远的影响。
目前的民用GPS设备包括测量型和导航型。测量产品的精度可以达到米甚至毫米,但至少需要两套(套)来满足设计精度要求,内部结构复杂,单机成本一般为数万至数十万,适合专业的高精度测量环境;导航产品,由于用户精度要求不高,一般为几十米,所以机器内部硬件相对简单,只有一个才能完成导航工作,价格相对较低,因此,它具有更大的广价值。
GPS该系统通常由地面控制站、导航卫星和用户接收(GPS移动用户端)由三部分组成。导航卫星至少24颗,均匀分布在6条极地轨道上,轨道夹角60度,距地平均高度20200公里,每12颗恒星绕地球一周。
GPS卫星发射的信号包含三种成分,即、和。这三种信号的重量是相同的基准频率F0=10.23MHZ产生的控制。
GPS两种卫星,即C/A代码和P码(或Y码)都是伪随机码。
1):它由两个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代码生成的原理及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比特),其中一部分闲置,5部分用于地面监控站,32部分用于不同的卫星。每颗卫星使用的不同部分都有相同的代码长度和周期,但结构不同。P捕获代码通常是先捕获的C/A然后根据导航电文信息捕获P码。因为P码的码元宽度是C/A代码的1/10,如果代码对齐精度仍然是代码宽度的1/100,则相应的距离误差为0.29m,所以P码叫精码。
它包括卫星参考星历、卫星工作状态、时间纠正参数、卫星钟运行状态、轨道摄入纠正、大气折射纠正和由C/A数据码(或D码)捕获P码等导航信息。
导航电文也是二进制码,按规定格式组成,按帧播放。每帧电文包含1500比特,播放速度50bit/s,每帧播放30次s。
每帧导航电文包含5个子帧,每个子帧包含10个字,每个字30比特,所以每个子帧共300比特,播放时间6s。为记载多达25颗卫星,子帧4、5各含有25页。每一页子帧1、2、3和子帧4、5构成一个主帧。主帧中1、2、3的内容每小时更新一次,4、5的内容只有在卫星注入新的导航电文后才能更新。
:
1、(TLM-Telemetry WORD)
作为捕获导航电文的前导,位于每个子帧的开头。
2、(交接字)(HOW-Hand Over Word)
接近每个子帧的遥测字,主要为用户提供用于捕获P码的Z记数。所谓Z记数,是从每周六/星期日晚上零点开始计算的时间记数(1.5s),表明下一子帧开始瞬间GPS时。
3、:包括卫星钟校正参数、数据年龄、周数、电离层校正参数、卫星工作状态等信息。 改正卫星钟的参数a0、a1、a2分别表示卫星的钟差、钟速和钟速变化率。任何时候t的钟改正数为: ?
t=a0 a1(t-t0c) a2(t-t0c)^2。
参考历元t0e从GPS从周六/周日夜零开始计算变化。于0-604800s之间。
数据龄期AODC表示卫星钟改正参数的参考时刻t0c与最近一次更新钟改正参数的时间TL之差,主要用于评价钟改正数的可信程度。
现时星期编号WN:表示从1980年1月6日协调时零点起算的GPS时星期数。
4、:包含在2、3两个子帧里,主要向用户提供有关计算该卫星运行位置的信息。该数据一般称为卫星星历,每30s重复1次,每小时更新一次。
5、:包含在4、5两个子帧中,主要向用户提供其他GPS卫星的概略星历及其工作状态信息,称为卫星的历书。第3数据块的内容每12.5分钟重复一次,每天更新一次。
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工程网等,这类网中的相邻点间的距离为几公里至几十公里,其主要任务是直接为国民经济建设服务。
二维位置的确定
由卫星产生的测距信号确定三维位置
有2维、3维两种坐标表示,当GPS能够收到4颗及以上卫星的信号时,它能计算出本地的3维坐标:经度、纬度、高度,若只能收到3颗卫星的信号,它只能计算出2维坐标:经度和纬度,这时它可能还会显示高度数据,但这数据是无效的。大部分GPS不仅能以经/纬度(Lat/Long) 的方式,显示坐标,而且还可以用 UTM(Universal TransverseMercator) 等坐标系统显示坐标但我们一般还是使用 LAT/LONG 系统,这主要是由你所使用的地图的坐标系统决定的。
GPS内存中保存的一个点的坐标值。在有GPS信号时,你可以存储成一个易认的名字,还可以给它选定一个图标。航点是GPS数据核心,它是构成“航线”的基础。标记航点是GPS主要功能之一,但是你也可以从地图上读出一个地点的坐标,手工或通过计算机接口输入GPS,成为一个航点。一个航点可以将来用于GOTO功能的目标,也可以选进一条航线 Route,作为一个支点。一般 GPS 能记录500个或以上的航点。
航线是GPS内存中存储的一组数据,包括一个起点和一个终点的坐标,还可以包括若干中间点的坐标,每两个坐标点之间的线段叫一条"腿"(leg) 。常见 GPS 能存储20条线路,每条线路30条"腿"。各坐标点可以从现有航点中选择,或是手工/计算机输入数值,输入的路点同时做为一个航点 (Waypoint/Landmark) 保存。
GPS没有指北针的功能,静止不动时它是不知道方向的。但是一旦动了起来,它就能知道自己的运动方向。GPS每隔一秒更新一次当前地点信息,每一点的坐标和上一点的坐标一比较,就可以知道前进的方向 。
导向功能在以下条件下起作用:
1.) 以设定"走向"(GOTO) 目标。"走向"目标的设定可以按"GOTO"键,然后从列表中选择一个航点。以后"导向"功能将导向此航点
2.) 目前有活跃航线 (Activity route)。活跃航线一般在设置 -> 航线菜单下设定。如果目前有活动航线,那么"导向"的点是航线中第一个路点,每到达一个路点后,自动指到下一个路点。
大多数GPS能够显示当地的日出、日落时间,这在计划出发 / 宿营时间时是有用的。这个时间是 GPS 根据当地经度和日期计算得到的,是指平原地区的日出、日落时间,在山区因为有山脊遮挡,日照时间根据情况要早晚各少半个小时以上。GPS的时间是从卫星信号得到的格林尼制时间,在设置 (setup) 菜单里可以设置本地的时间偏移,对中国来说,应设+8小时,此值只与时间的显示有关。
GPS每秒更新一次坐标信息,所以可以记载自己的运动轨迹。一般GPS能记录1024个以上足迹点,在一个专用页面上,以可调比例尺显示移动轨迹。足迹点的采样有自动和定时两种方式自动采样由 GPS 自动决定足迹点的采样方式,一般是只记录方向转折点,长距离直线行走时不记点;定时采样可以规定采样时间间隔,比如30秒、一分钟、 5 分钟或其他时间,每隔这么长时间记一个足迹点。
一台GPS设备关键的元件有天线、低噪音放大器(LNA)、射频接收转换(RF Section)、数字部分(也称数字基带,Digital Baseband)、微处理器(Microprocessor)、微处理器周边外设(Processor Peripherals)、输入输出和驱动(I/OandDriver)等几个部分。芯片提供商也强手如云,包括 SiRF、u-blox、Ti、Analog Devices、NXP、高通、英飞凌、索尼、意法半导体、Trimble(天宝)、Atmel、SiGe、u-Nav 等等。
1、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芯片组。
3、TI
TI的辅助GPS (A-GPS)解决方案在异步和同步蜂窝式网络内提供快速而精确的定位服务。这些解决方案在优化之后,适用于所有当前和发展中的无线标准(如 GSM、GPRS、EDGE、CDMA、UMTS 和 WCDMA)。 TI 在 2005 年推出的 90nm 工艺技术的单芯片 A-GPS 解决方案,GPS5300NaviLink 4.0单芯片采用 TI DRP技术,可实现离散的GPS解决方案。
4、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) 解决方案。
5、意法半导体
ST 也能够提供面向 GPS 应用的全系列解决方案,适用于车载与便携式导航系统。最新一代的 ST 导航/信息娱乐平台名为 NaviFlex,其集成度更高:融合 GPS 接收器和 Nomadik 应用处理器,保证了汽车多媒体应用无与伦比的音频、视频和成像质量。
6、Maxim
Maxim 公司能够提供低噪声、低功耗的GPS前端接收器和独特的GPS方案。
7、NXP
恩智浦半导体 (NXP Semiconductors,原飞利浦半导体),恩智浦的解决方案成功地将高质量导航功能与丰富的多媒体处理结合在一起,包括 MP3 播放、标准的以及高清晰的视频播放及录制、调频收音机、图像存储和游戏等。
8、英飞凌
Infineon和Global Locate合作推出的Hammerhead是全球首款单芯片CMOS GPS 接收器。该芯片支持移动站辅助式(MS-A)、移动站基于式(MS-B)、自主式和增强式跟踪模式。一流的室内信号跟踪效果,完全支持辅助式和自主式跟踪模式,即使在最微弱的信号环境中也可以进行高度精确的导航。Hammerhead 芯片的基于主机的软件架构,不仅将器件尺寸和成本减至最小,还允许将协议消息直接嵌入到 GPS 导航软件中。
9、U-Blox
来自瑞士的GPS技术公司u-blox AG公司以往主要提供命名为 TIM的GPS 模块,其中采用的SiRF公司GPS芯片。现在u-blox 也开始注重核心芯片的开发。新推出的 u-blox 5 系列全球定位系统以及随时可用的伽利略系统单芯片和芯片组拥有不到一秒的接收性能。这种新的芯片还拥有 SuperSense-160 dBm 探测和跟踪灵敏度、小于 50mW 的功率需求以及一个小于 100 平方毫米的覆盖区,适用于掌上电脑(PDA)、个人导航设备、照相机、手机、媒体播放器和其它电池操作便携式设备。
10、高通
目前,全球已有总计超过两亿部手机装备了高通公司的gpsOne辅助型GPS 技术。gpsOne 技术支持一系列极具吸引力的位置服务,其中包括各种各样针对消费者、商务和个人安全的应用。
模块输出信息主要包括4个部分:
1、GPS定位信息GPGGA(Global Positioning SystemFix Data)
- $GPGGA,063740.998,2234.2551,N,11408.0339,E,1,08,00.9,00053.A,M,-2.1,M,,*7B
- $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
- <1> UTC时间,hhmmss(时分秒)格式
- <2> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
- <3> 纬度半球N(北半球)或S(南半球)
- <4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
- <5> 经度半球E(东经)或W(西经)
- <6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
- <7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)
- <8> HDOP水平精度因子(0.5~99.9)
- <9> 海拔高度(-9999.9~99999.9)
- <10> 地球椭球面相对大地水准面的高度
- <11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
- <12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)
2、当前卫星信息GPGSA(GPS DOP and ActiveSatellites)
- $GPGSA,A,3,06,16,14,22,25,01,30,20,,,,,01.6,00.9,01.3*0D
- $GPGSA,<1>,<2>,<3>,<3>,,,,,<3>,<3>,<3>,<4>,<5>,<6>,<7><CR><LF>
- <1>模式 :M = 手动, A = 自动。
- <2>定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。
- <3>PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收12颗卫星信息。
- <4> PDOP位置精度因子(0.5~99.9)
- <5> HDOP水平精度因子(0.5~99.9)
- <6> VDOP垂直精度因子(0.5~99.9)
- <7> Checksum.(检查位).
3、可见卫星信息GPGSV(GPS Satellites in View)
- $GPGSV,2,1,08,06,26,075,44,16,50,227,47,14,57,097,44,22,17,169,41*70
- $GPGSV,2,2,08,25,49,352,45,01,64,006,45,30,13,039,39,20,15,312,34*7A
- $GPGSV,<1>,<2>,<3>,<4>,<5>,<6>,<7>,?<4>,<5>,<6>,<7>,<8><CR><LF>
- <1> GSV语句的总数
- <2> 本句GSV的编号
- <3> 可见卫星的总数,00 至 12。
- <4> 卫星编号, 01 至 32。
- <5>卫星仰角, 00 至 90 度。
- <6>卫星方位角, 000 至 359 度。实际值。
- <7>讯号噪声比(C/No), 00 至 99 dB;无表未接收到讯号。
- <8>Checksum.(检查位).
- 第<4>,<5>,<6>,<7>项个别卫星会重复出现,每行最多有四颗卫星。其余卫星信息会于次一行出现,若未使用,这些字段会空白。
4、推荐最小定位信息GPRMC(Recommended MinimumSpecific GPS/TRANSIT Data)
- $GPRMC,012724.000,A,2234.3157,N,11408.0921,E,0.00,,290108,,,A*71
- $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
- <1> UTC时间,hhmmss(时分秒)格式
- <2> 定位状态,A=有效定位,V=无效定位
- <3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
- <4> 纬度半球N(北半球)或S(南半球)
- <5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
- <6> 经度半球E(东经)或W(西经)
- <7> 地面速率(000.0~999.9节,前面的0也将被传输)
- <8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
- <9> UTC日期,ddmmyy(日月年)格式
- <10> 磁偏角(000.0~180.0度,前面的0也将被传输)
- <11> 磁偏角方向,E(东)或W(西)
- <12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
- 我们所关心的是GPRMC这条信息,因为其中包括当前格林威治时间、经度、纬度、日期等。
UART接口,与gps模块通信,即读取gps的信息。
因为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这个结构体。
- /** Represents a location. */
- typedef struct {
- /**set to sizeof(GpsLocation) */
- size_t size;
- /**Contains GpsLocationFlags bits. */
- uint16_t flags;
- /**Represents latitude in degrees. */
- double latitude;
- /**Represents longitude in degrees. */
- double longitude;
- /**Represents altitude in meters above the WGS 84 reference
- *ellipsoid. */
- double altitude;
- /**Represents speed in meters per second. */
- float speed;
- /**Represents heading in degrees. */
- float bearing;
- /**Represents expected accuracy in meters. */
- float accuracy;
- /**Timestamp for the location fix. */
- GpsUtcTime timestamp;
- } GpsLocation;
所有我们要知道的数据都在这里了:经度、纬度、海拔、速度、精确度、世界标准时间等。而上层也只是需要这个数据结构,所以只要把这个数据结构给android上层,那么就OK了。
下面还是主要分析下android模拟器是如何实现的。先看下简单的流程图:
首先看下hw主要结构体,gps是注册为hw模块的。编译后是生成gps.*.so的,而他的方法是调用gps_module_methods。
- const struct hw_module_t HAL_MODULE_INFO_SYM = {
- .tag =HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id =GPS_HARDWARE_MODULE_ID,
- .name ="Goldfish GPS Module",
- .author ="The Android Open Source Project",
- .methods =&gps_module_methods,
- };
- 而gps_module_methods又调用了open_gps
- static struct hw_module_methods_t gps_module_methods ={
- .open = open_gps
- };
再看看open_gps做了什么,初始化了很多函数指针,具体含义可以看
- static constGpsInterface qemuGpsInterface = {
- sizeof(GpsInterface),
- qemu_gps_init, //打开接口,提供callback函数
- qemu_gps_start, //开始导航
- qemu_gps_stop, //停止导航
- qemu_gps_cleanup, //关闭接口
- qemu_gps_inject_time,//注入当前时间
- qemu_gps_inject_location, //注入从其他定位方式得的当前位置。
- qemu_gps_delete_aiding_data, //
- qemu_gps_set_position_mode, //设置坐标模式
- qemu_gps_get_extension, //扩展信息
- };
然后再看看各个函数,这些函数是jni层会调用到的,这里简单介绍初始化、数据上报等操作。
首先是初始化函数qemu_gps_init,这里调用了gps_state_init函数,然后在这里打开我们要的串口驱动设备,开启读取gps数据的线程。
- state->fd = open(GPS_Serial_Name, O_RDONLY );
- state->thread = callbacks->eate_thread_cb("gps_state_thread”,gps_state_thread, tate);
当线程启动以后,那么就会在这个线程中处理一些事情了,接着看下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
- else if ( !memcmp(tok.p, "GLL", 3) )
- else if ( !memcmp(tok.p, "GSA", 3) )
- else if ( !memcmp(tok.p, "GSV", 3) )
其他的依次都差不多。具体可以看源码。
最后处理完了以后,把便要把数据给jni层了。通过r->callback( &r->fix );这个callback函数,就是数据传输的主要函数了。
先还是看下jni层的主要流程吧:分为1、Java到jni到hal和2、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方法的回调函数了。
- jniRegisterNativeMethods(env,"com/android/server/location/GpsLocationProvider", sMethods,NELEM(sMethods));
下面的是native方法的一些函数。