日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

和菜鸟一起学android4.0.3源码之硬件gps简单移植【转】

發布時間:2024/8/1 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 和菜鸟一起学android4.0.3源码之硬件gps简单移植【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉載自:http://blog.csdn.net/mwj19890829/article/details/18751447

關于Android定位方式

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和CDMA2000網絡中進行使用。該技術需要在手機內增加GPS接收機模塊并改造手機的天線,同時要在移動網絡上加建位置服務器、差分GPS基準站等設備。AGPS解決方案的優勢主要體現在其定位精度上在室外等空曠地區其精度在正常的GPS工作環境下可以達到10米左右,堪稱目前定位精度最高的一種定位技術。該技術的另一優點為首次捕獲GPS信號的時間一般僅需幾秒,不像GPS的首次捕獲時間可能要2-3分鐘。

關于android上的gps定位

關于gps定位,從衛星信號到android終端地圖顯示的整體流程圖如下:

以下簡單介紹下GPS定位的相關知識

一、GPS簡介

GPS(Global Positioning System), 即全球定位系統,它是一個由覆蓋全球的24顆衛星組成的衛星系統。其目的是在全球范圍內對地面和空中目標進行準確定位和監測。隨著全球性空間定位信息應用的日益廣泛,GPS提供的全時域、全天候、高精度定位服務將給空間技術、地球物理、大地測繪、遙感技術、交通調度、軍事作戰以及人們的日常生活帶來巨大的變化和深遠的影響。

目前的民用GPS設備包括測量型和導航型。其中測量型產品的精度可達到米級甚至毫米級,但至少需要兩臺(套)才能達到設計精度要求,而且其內部結構復雜,單機成本一般在幾萬到幾十萬,適合專業高精度測量環境使用;導航型產品,由于其使用者對精度要求不高,一般為幾十米,因此機器內部硬件相對簡單,只須一臺就可以完成導航工作,加之其價格相對較低,因而更有普及和推廣價值。

GPS系統一般由地面控制站、導航衛星和用戶接收機(GPS的移動用戶端)三大部分組成。導航衛星至少24顆,均勻分布在6個極地軌道上,軌道的夾角為60度,距地平均高度為20200公里,每12恒星時繞地球一周。

二、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顆衛星,子幀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、數據塊1:含有衛星鐘改正參數及數據齡期、星期的周數編號、電離層改正參數、和衛星工作狀態等信息。 衛星鐘改正參數a0、a1、a2分別表示該衛星的鐘差、鐘速和鐘速變化率。任意時刻t的鐘改正數為: ?

t=a0+a1(t-t0c)+a2(t-t0c)^2。

參考歷元t0e為數據塊1的基準時間,從GPS時星期六/星期日子夜零時起算,變化于0-604800s之間。

數據齡期AODC表示衛星鐘改正參數的參考時刻t0c與最近一次更新鐘改正參數的時間TL之差,主要用于評價鐘改正數的可信程度。

現時星期編號WN:表示從1980年1月6日協調時零點起算的GPS時星期數。

4、數據塊2:包含在2、3兩個子幀里,主要向用戶提供有關計算該衛星運行位置的信息。該數據一般稱為衛星星歷,每30s重復1次,每小時更新一次。

5、數據塊3:包含在4、5兩個子幀中,主要向用戶提供其他GPS衛星的概略星歷及其工作狀態信息,稱為衛星的歷書。第3數據塊的內容每12.5分鐘重復一次,每天更新一次。

三、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 分鐘或其他時間,每隔這么長時間記一個足跡點。

四、主流GPS方案供應商

一臺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

2、Nemerix?

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 技術支持一系列極具吸引力的位置服務,其中包括各種各樣針對消費者、商務和個人安全的應用。

五、GPS標準格式數據

?

模塊輸出信息主要包括4個部分:

1、GPS定位信息GPGGA(Global Positioning SystemFix Data)

[html]?view plaincopy
  • $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)

    [html]?view plaincopy
  • $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)?????

    [html]?view plaincopy
  • $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)

    [html]?view plaincopy
  • $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這條信息,因為其中包括當前格林威治時間、經度、緯度、日期等。??
  • 六、Linux?driver層

    ?????? UART接口,與gps模塊通信,即讀取gps的信息。

    七、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這個結構體。

    [html]?view plaincopy
  • /**?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。

    [html]?view plaincopy
  • 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做了什么,初始化了很多函數指針,具體含義可以看

    [html]?view plaincopy
  • 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數據的線程。

    [html]?view plaincopy
  • 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層。

    [html]?view plaincopy
  • nmea_reader_set_callback(?reader,state->callbacks.location_cb?);??
  • 串口讀取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

    [html]?view plaincopy
  • 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函數,就是數據傳輸的主要函數了。

    八、android GPS的JNI層

    先還是看下jni層的主要流程吧:分為1、Java到jni到hal和2、hal到jni到java。

    ?

    GPS的jni的代碼是在下面這個目錄下的:

    [html]?view plaincopy
  • /framework/base/services/jni/com_android_server_location_GpsLocationProvider.cpp??
  • 在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方法的回調函數了。

    [html]?view plaincopy
  • jniRegisterNativeMethods(env,"com/android/server/location/GpsLocationProvider",?sMethods,NELEM(sMethods));??
  • 下面的是native方法的一些函數。

    [html]?view plaincopy
  • staticJNINativeMethod?sMethods[]?=?{??
  • {"class_init_native","()V",?(void*)android_location_GpsLocationProvider_class_init_native},??
  • ????{"native_is_supported","()Z",(void*)android_location_GpsLocationProvider_is_supported},??
  • ????{"native_init",?"()Z",(void*)android_location_GpsLocationProvider_init},??
  • ????{"native_cleanup","()V",?(void*)android_location_GpsLocationProvider_cleanup},??
  • {"native_set_position_mode","(IIIII)Z",(void*)android_location_GpsLocationProvider_set_position_mode},??
  • ????{"native_start",?"()Z",(void*)android_location_GpsLocationProvider_start},??
  • ????{"native_stop",?"()Z",(void*)android_location_GpsLocationProvider_stop},??
  • …………………………??
  • };??
  • 對于這個method做一些簡單的解釋吧:。

    第一個參數name是在java服務層定義的native函數。具體可以看

    frameworks/base/location/java/com/android/server/location/GpsLocationProvide.java下的代碼。

    這個稍后分析。

    第二個參數signature是java服務層調用jni層的參數,具體的可以先看下面這個表:

    [html]?view plaincopy
  • 字符???Java類型????C類型??
  • V??????void?????????void??
  • Z???????jboolean?????boolean??
  • I????????jint?????????int??
  • J???????jlong????????long??
  • D??????jdouble???????double??
  • F??????jfloat?????????float??
  • B??????jbyte?????????byte??
  • C??????jchar?????????char??
  • S??????jshort?????????short??
  • 數組則以"["開始,用兩個字符表示

    [html]?view plaincopy
  • ???
  • [I???????jintArray??????int[]??
  • [F?????jfloatArray??????float[]??
  • [B?????jbyteArray??????byte[]??
  • [C????jcharArray???????char[]??
  • [S????jshortArray???????short[]??
  • [D????jdoubleArray?????double[]??
  • [J?????jlongArray???????long[]??
  • [Z????jbooleanArray?????boolean[]??
  • ???
  • 實際上這些字符是與函數的參數類型一一對應的。

    "()"中的字符表示參數,后面的則代表返回值。例如"()V" 就表示void Func();

    "(II)V"表示 void Func(int, int);

    上面的都是基本類型。如果Java函數的參數是class,則以"L"開頭,以";"結尾中間是用"/" 隔開的包及類名。而其對應的C函數名的參數則為jobject. 一個例外是String類,其對應的類為jstring

    [html]?view plaincopy
  • Ljava/lang/String;String?jstring??
  • Ljava/net/Socket;Socket?jobject??
  • 如果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代碼了。

    1、首先是android_location_GpsLocationProvider_class_init_native這個函數了。

    [html]?view plaincopy
  • method_reportLocation?=env->GetMethodID(clazz,?"reportLocation","(IDDDFFFJ)V");??
  • ????……………………………………??
  • ???method_requestUtcTime?=?env->GetMethodID(clazz,"requestUtcTime","()V")??
  • 他先是獲取所有的方法id。然后調用hw模塊,也就是上面hal層編譯的gps.*.so鏈接庫

    [html]?view plaincopy
  • err?=hw_get_module(GPS_HARDWARE_MODULE_ID,?(hw_module_t?const**)&module);??
  • 然后調用了hal層的gps的open函數了。

    [html]?view plaincopy
  • err?=module->methods->open(module,?GPS_HARDWARE_MODULE_ID,?&device);??
  • 獲取接口sGpsInterface =gps_device->get_gps_interface(gps_device);

    因為是gps不是agps所以

    [html]?view plaincopy
  • sGpsXtraInterface?=??
  • ??????????(constGpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);??
  • 2、接著便是android_location_GpsLocationProvider_init這個初始化函數了。

    ?????? 該函數主要是調用了

    [html]?view plaincopy
  • if(sGpsXtraInterface?&&sGpsXtraInterface->init(&sGpsXtraCallbacks)?!=?0)??
  • ????????sGpsXtraInterface?=?NULL;??
  • 這個函數的函數指針init就調用到hal層的init函數。也就是qemu_gps_init函數了。

    這里傳進來了callback函數了。

    具體如下:

    [html]?view plaincopy
  • GpsCallbackssGpsCallbacks?=?{??
  • ????sizeof(GpsCallbacks),??
  • ????location_callback,??//回調位置信息??
  • ????status_callback,????//回調狀態信息??
  • ????sv_status_callback,??//回調sv狀態信息??
  • ????nmea_callback,????//上報nema信息??
  • ????set_capabilities_callback,?//回調告知框架層GPS的性能??
  • ????acquire_wakelock_callback,?//獲取GPS鎖,不進行休眠??
  • ????release_wakelock_callback,?//釋放GPS鎖??
  • ????create_thread_callback,?//創建線程,可以調用java?framework的代碼??
  • ????request_utc_time_callback,?//獲取utc時間??
  • };??
  • 具體函數可以看下面:

    [html]?view plaincopy
  • staticvoid?location_callback(GpsLocation*?location)??
  • {??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ????env->CallVoidMethod(mCallbacksObj,?method_reportLocation,location->flags,??
  • ????????????(jdouble)location->latitude,(jdouble)location->longitude,??
  • ????????????(jdouble)location->altitude,??
  • ????????????(jfloat)location->speed,(jfloat)location->bearing,??
  • ????????????(jfloat)location->accuracy,(jlong)location->timestamp);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • 這里會調用method_reportLocation這個方法,這個方法是在java服務層調用的。這里通過CallVoidMethod函數調用了Java?framework的函數。

    [html]?view plaincopy
  • staticvoid?status_callback(GpsStatus*?status)??
  • {??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ???env->CallVoidMethod(mCallbacksObj,?method_reportStatus,status->status);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • ???
  • staticvoid?sv_status_callback(GpsSvStatus*?sv_status)??
  • {??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ????memcpy(&sGpsSvStatus,?sv_status,sizeof(sGpsSvStatus));??
  • ????env->CallVoidMethod(mCallbacksObj,method_reportSvStatus);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • ???
  • staticvoid?nmea_callback(GpsUtcTime?timestamp,?const?char*?nmea,?int?length)??
  • {??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ????//?The?Java?code?will?call?back?to?readthese?values??
  • ????//?We?do?this?to?avoid?creating?unnecessaryString?objects??
  • ????sNmeaString?=?nmea;??
  • ????sNmeaStringLength?=?length;??
  • ????env->CallVoidMethod(mCallbacksObj,method_reportNmea,?timestamp);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • ???
  • staticvoid?set_capabilities_callback(uint32_t?capabilities)??
  • {??
  • ????LOGD("set_capabilities_callback:%ld\n",?capabilities);??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ????env->CallVoidMethod(mCallbacksObj,method_setEngineCapabilities,?capabilities);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • ???
  • staticvoid?acquire_wakelock_callback()??
  • {??
  • ????acquire_wake_lock(PARTIAL_WAKE_LOCK,WAKE_LOCK_NAME);??
  • }??
  • 獲取GPS的鎖??
  • staticvoid?release_wakelock_callback()??
  • {??
  • ????release_wake_lock(WAKE_LOCK_NAME);??
  • }??
  • 釋放了GPS的鎖??
  • staticvoid?request_utc_time_callback()??
  • {??
  • ????JNIEnv*?env?=?AndroidRuntime::getJNIEnv();??
  • ????env->CallVoidMethod(mCallbacksObj,method_requestUtcTime);??
  • ????checkAndClearExceptionFromCallback(env,__FUNCTION__);??
  • }??
  • 更新時間??
  • staticpthread_t?create_thread_callback(const?char*?name,?void?(*start)(void?*),?void*arg)??
  • {??
  • ????return(pthread_t)AndroidRuntime::createJavaThread(name,?start,?arg);??
  • }??
  • 創建線程。??
  • 3、其他函數,開啟導航,關閉導航等的就不一一介紹了,和上面的類似。可以看源碼。

    好了,jni層就大概分析好了,那么接著就是framework層的代碼了。

    九、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函數,

    [html]?view plaincopy
  • System.loadLibrary("android_servers");??
  • ??????init1(args);??
  • 加載庫,然后就是調用了jni層的init1函數。

    [html]?view plaincopy
  • static?voidandroid_server_SystemServer_init1(JNIEnv*?env,?jobject?clazz)??
  • {??
  • ???system_init();??
  • }??
  • 其調用了system_init();函數,而在system_init函數中

    [html]?view plaincopy
  • jmethodID?methodId?=env->GetStaticMethodID(clazz,?"init2",?"()V");??
  • env->CallStaticVoidMethod(clazz,methodId);??
  • 他又回調了SystemServer.Java中的init2函數。

    在init2函數中

    [html]?view plaincopy
  • public?static?final?void?init2()?{??
  • ???????Slog.i(TAG,?"Entered?the?Android?system?server!");??
  • ???????Thread?thr?=?new?ServerThread();??
  • ???????thr.setName("android.server.ServerThread");??
  • ???????thr.start();??
  • ????}??
  • 創建了一個線程,最后他會調用到ServerThread的run方法。

    在其run()方法中會啟動很多服務,比如Account Manager、ContentManager、System Content Providers、Lights Service、BatteryService、Vibrator Service、Alarm Manager、InitWatchdog、Window Manager等等,我們這里最主要的就是關注LocationManagerService。

    [html]?view plaincopy
  • try?{??
  • ????????????????Slog.i(TAG,?"LocationManager");??
  • ????????????????location?=?new?LocationManagerService(context);??
  • ???????????????ServiceManager.addService(Context.LOCATION_SERVICE,?location);??
  • ????????????}?catch?(Throwable?e)?{??
  • ????????????????reportWtf("startingLocation?Manager",?e);??
  • ???????????}??
  • 這里new了一個LocationManagerService對象,并且添加了這個service。

    然后finalLocationManagerService locationF = location;

    [html]?view plaincopy
  • try?{??
  • ????????????????????if?(locationF?!=?null)locationF.systemReady();??
  • ????????????????}?catch?(Throwable?e)?{??
  • ????????????????????reportWtf("makingLocation?Service?ready",?e);??
  • ????????????????}??
  • 當activity manager好了之后就調用了locationF.systemReady();函數了。

    下面進LocationManagerService.java中的system函數。

    [html]?view plaincopy
  • voidsystemReady()?{??
  • ????????//?we?defer?starting?up?the?service?untilthe?system?is?ready??
  • ????????Thread?thread?=?new?Thread(null,?this,"LocationManagerService");??
  • ????????thread.start();??
  • ????}??
  • 這里創建了一個線程,然后線程啟動了,接著他會調用run方法。也就是

    [html]?view plaincopy
  • publicvoid?run()??
  • ????{??
  • ????????Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);??
  • ????????Looper.prepare();??
  • ????????mLocationHandler?=?newLocationWorkerHandler();??
  • ????????initialize();??
  • ????????Looper.loop();??
  • ????}??
  • 在run方法中,他會初始化一些東東,也就是initialize();函數了。

    [html]?view plaincopy
  • privatevoid?initialize()?{??
  • ????????//?Create?a?wake?lock,?needs?to?be?donebefore?calling?loadProviders()?below??
  • ????????PowerManager?powerManager?=(PowerManager)??
  • mContext.getSystemService(Context.POWER_SERVICE);??
  • ????????mWakeLock?=??
  • powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,WAKELOCK_KEY);??
  • ???
  • ????????//?Load?providers??
  • ????????loadProviders();??
  • ………………??
  • ………………??
  • }??
  • 這里主要看loadProviders();函數。

    [html]?view plaincopy
  • privatevoid?loadProviders()?{??
  • ????????synchronized?(mLock)?{??
  • ????????????if?(sProvidersLoaded)?{??
  • ????????????????return;??
  • ????????????}??
  • ???
  • ????????????//?Load?providers??
  • ????????????loadProvidersLocked();??
  • ????????????sProvidersLoaded?=?true;??
  • ????????}??
  • ????}??
  • 這里又會調用loadProvidersLocked(),然后是_loadProvidersLocked()函數。其中就會調用到我們需要的gpsprovider了。

    [html]?view plaincopy
  • if(GpsLocationProvider.isSupported())?{??
  • ????????????//?Create?a?gps?location?provider??
  • ????????????GpsLocationProvider?gpsProvider?=new?GpsLocationProvider(mContext,?this);??
  • ????????????mGpsStatusProvider?=gpsProvider.getGpsStatusProvider();??
  • ????????????mNetInitiatedListener?=gpsProvider.getNetInitiatedListener();??
  • ????????????addProvider(gpsProvider);??
  • ????????????mGpsLocationProvider?=?gpsProvider;??
  • ????????}??
  • 在new一個GpsLocationProvider的時候會開一個GpsLocationProviderThread的線程

    [html]?view plaincopy
  • mThread?=new?GpsLocationProviderThread();??
  • mThread.start();??
  • 然后啟動了線程,在這里會初始化,然后主要還是new了一個ProviderHandler的類。

    [html]?view plaincopy
  • initialize();??
  • ?????????mHandler?=?new?ProviderHandler();??
  • 這個類中

    [html]?view plaincopy
  • publicvoid?handleMessage(Message?msg)?{??
  • ????????????int?message?=?msg.what;??
  • ????????????switch?(message)?{??
  • ????????????????case?ENABLE:??
  • ????????????????????if?(msg.arg1?==?1)?{??
  • ????????????????????????handleEnable();??
  • ????????????????????}?else?{??
  • ????????????????????????handleDisable();??
  • ????????????????????}??
  • ????????????????????break;??
  • ????????????????case?ENABLE_TRACKING:??
  • ???????????????????handleEnableLocationTracking(msg.arg1?==?1);??
  • ????????????????????break;??
  • ????????????????case?REQUEST_SINGLE_SHOT:??
  • ????????????????????handleRequestSingleShot();??
  • ????????????????????break;??
  • ????????????????case?UPDATE_NETWORK_STATE:??
  • ???????????????????handleUpdateNetworkState(msg.arg1,?(NetworkInfo)msg.obj);??
  • ????????????????????break;??
  • ????????????????case?INJECT_NTP_TIME:??
  • ????????????????????handleInjectNtpTime();??
  • ????????????????????break;??
  • ????????????????case?DOWNLOAD_XTRA_DATA:??
  • ????????????????????if?(mSupportsXtra)?{??
  • ????????????????????????handleDownloadXtraData();??
  • ????????????????????}??
  • ????????????????????break;??
  • ????????????????case?UPDATE_LOCATION:??
  • ???????????????????handleUpdateLocation((Location)msg.obj);??
  • ????????????????????break;??
  • ????????????????case?ADD_LISTENER:??
  • ????????????????????handleAddListener(msg.arg1);??
  • ????????????????????break;??
  • ????????????????case?REMOVE_LISTENER:??
  • ???????????????????handleRemoveListener(msg.arg1);??
  • ????????????????????break;??
  • ????????????}??
  • 就會處理很多事情了。具體可以看上面的代碼。

    接著他調用了updateProvidersLocked();這個函數。

    updateProviderListenersLocked(name,true);

    然后就啟動了gps服務了

    [html]?view plaincopy
  • if?(enabled)?{??
  • ????????????p.enable();??
  • ????????????if?(listeners?>?0)?{??
  • ???????????????p.setMinTime(getMinTimeLocked(provider),?mTmpWorkSource);??
  • ????????????????p.enableLocationTracking(true);??
  • ????????????}??
  • ????????}??
  • 接著我們開始往GpsLocationProvide.java這里看

    [html]?view plaincopy
  • public?void?enable()?{??
  • ????????synchronized?(mHandler)?{??
  • ????????????sendMessage(ENABLE,?1,?null);??
  • ????????}??
  • ????}??
  • 這里發送了一個ENABLE消息,然后就會調用到上面ProviderHandler的函數,handleEnable();

    [html]?view plaincopy
  • privatevoid?handleEnable()?{??
  • ???????……??
  • ????????mEnabled?=?native_init();??
  • ???
  • ????????if?(mEnabled)?{??
  • ????????????mSupportsXtra?=native_supports_xtra();??
  • ???????……??
  • ????}??
  • 這里就會調用到了jni的native函數了。

    而native的所有函數,在jni中我們都已經分析過了。

    接著便是

    enable函數結束后,那便是

    [html]?view plaincopy
  • publicvoid?enableLocationTracking(boolean?enable)?{??
  • ????????//?FIXME?-?should?set?a?flag?here?to?avoidrace?conditions?with?single?shot?request??
  • ????????synchronized?(mHandler)?{??
  • ????????????sendMessage(ENABLE_TRACKING,(enable???1?:?0),?null);??
  • ????????}??
  • ????}??
  • 同樣,他也發送了ENABLE_TRACKING的消息,接著調用

    [html]?view plaincopy
  • handleEnableLocationTracking(msg.arg1==?1);??
  • if?(enable)?{??
  • ????????????mTTFF?=?0;??
  • ????????????mLastFixTime?=?0;??
  • ????????????startNavigating(false);??
  • ????????}??
  • 接著調用了startNavigating函數,

    [html]?view plaincopy
  • privatevoid?startNavigating(boolean?singleShot)?{??
  • ???????……??
  • ?if?(!native_set_position_mode(mPositionMode,GPS_POSITION_RECURRENCE_PERIODIC,??
  • ????interval,?0,?0))?{??
  • ????????????????mStarted?=?false;??
  • ????????????????Log.e(TAG,"set_position_mode?failed?in?startNavigating()");??
  • ????????????????return;??
  • ???}??
  • ????if(!native_start())?{??
  • ?????????mStarted?=?false;??
  • ?????????Log.e(TAG,?"native_start?failedin?startNavigating()");??
  • ????????return;??
  • ????……??
  • ???}??
  • }??
  • 這里主要還是設置position mode,然后啟動了。

    接下來,我們看看,jni調用的一些callback函數在這里做了些什么。

    首先就是reportLocation函數了。

    [html]?view plaincopy
  • privatevoid?reportLocation(int?flags,?double?latitude,?double?longitude,?doublealtitude,??
  • ????????????float?speed,?float?bearing,?floataccuracy,?long?timestamp)?{??
  • ????????…………??
  • ????????synchronized?(mLocation)?{??
  • ????????????mLocationFlags?=?flags;??
  • ????????????if?((flags?&LOCATION_HAS_LAT_LONG)?==?LOCATION_HAS_LAT_LONG)?{??
  • ???????????????mLocation.setLatitude(latitude);??
  • ???????????????mLocation.setLongitude(longitude);??
  • ????????????????mLocation.setTime(timestamp);??
  • ????????????}??
  • ????????????if?((flags?&LOCATION_HAS_ALTITUDE)?==?LOCATION_HAS_ALTITUDE)?{??
  • ????????????????mLocation.setAltitude(altitude);??
  • ????????????}?else?{??
  • ????????????????mLocation.removeAltitude();??
  • ????????????}??
  • ????????????if?((flags?&LOCATION_HAS_SPEED)?==?LOCATION_HAS_SPEED)?{??
  • ????????????????mLocation.setSpeed(speed);??
  • ????????????}?else?{??
  • ????????????????mLocation.removeSpeed();??
  • ????????????}??
  • ????????????if?((flags?&LOCATION_HAS_BEARING)?==?LOCATION_HAS_BEARING)?{??
  • ????????????????mLocation.setBearing(bearing);??
  • ????????????}?else?{??
  • ????????????????mLocation.removeBearing();??
  • ????????????}??
  • ????????????if?((flags?&?LOCATION_HAS_ACCURACY)?==LOCATION_HAS_ACCURACY)?{??
  • ???????????????mLocation.setAccuracy(accuracy);??
  • ????????????}?else?{??
  • ????????????????mLocation.removeAccuracy();??
  • ????????????}??
  • ???
  • ????????????try?{??
  • ????????????????mLocationManager.reportLocation(mLocation,false);??
  • ????????????}?catch?(RemoteException?e)?{??
  • ????????????????Log.e(TAG,"RemoteException?calling?reportLocation");??
  • ????????????}??
  • ????????}??
  • ???
  • ????????mLastFixTime?=System.currentTimeMillis();??
  • ????????//?report?time?to?first?fix??
  • ????????if?(mTTFF?==?0?&&?(flags?&LOCATION_HAS_LAT_LONG)?==?LOCATION_HAS_LAT_LONG)?{??
  • ????????????mTTFF?=?(int)(mLastFixTime?-mFixRequestTime);??
  • ????????????if?(DEBUG)?Log.d(TAG,?"TTFF:"?+?mTTFF);??
  • ???
  • ????????????//?notify?status?listeners??
  • ????????????synchronized(mListeners)?{??
  • ????????????????int?size?=?mListeners.size();??
  • ????????????????for?(int?i?=?0;?i?<?size;i++)?{??
  • ????????????????????Listener?listener?=mListeners.get(i);??
  • ????????????????????try?{??
  • ???????????????????????listener.mListener.onFirstFix(mTTFF);??
  • ????????????????????}?catch?(RemoteException?e){??
  • ????????????????????????Log.w(TAG,"RemoteException?in?stopNavigating");??
  • ???????????????????????mListeners.remove(listener);??
  • ????????????????????????//?adjust?for?size?oflist?changing??
  • ????????????????????????size--;??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ???
  • ????????if?(mSingleShot)?{??
  • ????????????stopNavigating();??
  • ????????}??
  • ????????if?(mStarted?&&?mStatus?!=LocationProvider.AVAILABLE)?{??
  • ????????????//?we?want?to?time?out?if?we?do?notreceive?a?fix??
  • ????????????//?within?the?time?out?and?we?arerequesting?infrequent?fixes??
  • ????????????if(!hasCapability(GPS_CAPABILITY_SCHEDULING)?&&?mFixInterval?<NO_FIX_TIMEOUT)?{??
  • ???????????????mAlarmManager.cancel(mTimeoutIntent);??
  • ????????????}??
  • ???
  • ????????????//?send?an?intent?to?notify?that?the?GPSis?receiving?fixes.??
  • ????????????Intent?intent?=?newIntent(LocationManager.GPS_FIX_CHANGE_ACTION);??
  • ???????????intent.putExtra(LocationManager.EXTRA_GPS_ENABLED,?true);??
  • ????????????mContext.sendBroadcast(intent);??
  • ???????????updateStatus(LocationProvider.AVAILABLE,?mSvCount);??
  • ????????}??
  • ???
  • ???????if(!hasCapability(GPS_CAPABILITY_SCHEDULING)?&&?mStarted?&&mFixInterval?>?1000)?{??
  • ????????????if?(DEBUG)?Log.d(TAG,?"gotfix,?hibernating");??
  • ????????????hibernate();??
  • ????????}??
  • ???}??
  • 這里對于jni層獲取的數據,做了處理后,更新了location信息。

    其中下面這些都是給應用層的接口。

    [html]?view plaincopy
  • ???????????mLocation.setLatitude(latitude);??
  • Location.setLongitude(longitude);??
  • mLocation.setTime(timestamp);??
  • Ok,那么framwork層就介紹到這里了。

    十、android GPS的APP層

    首先看流程:

    接上面的framework層,這里調用了mLocation是new了一個Location的類,這個類主要是給應用層接口的。

    [html]?view plaincopy
  • if((flags?&?LOCATION_HAS_LAT_LONG)?==?LOCATION_HAS_LAT_LONG)?{??
  • ???????????????mLocation.setLatitude(latitude);??
  • ???????????????mLocation.setLongitude(longitude);??
  • ????????????????mLocation.setTime(timestamp);??
  • ????????????}??
  • 其代碼在frameworks/base/location/java/android/location/Location.java

    取其中一部分的函數做下簡單的介紹。

    [html]?view plaincopy
  • /**??
  • ?*?Sets?the?UTC?time?of?this?fix,?inmilliseconds?since?January?1,??
  • ?*?1970.??
  • ?*/??
  • public?void?setTime(long?time)?{??
  • ????mTime?=?time;??
  • }??
  • ??
  • /**??
  • ?*?Returns?the?latitude?of?this?fix.??
  • ?*/??
  • public?double?getLatitude(){??
  • ????return?mLatitude;??
  • }??
  • ??
  • /**??
  • ?*?Sets?the?latitude?of?this?fix.??
  • ?*/??
  • public?void?setLatitude(double?latitude)?{??
  • ????mLatitude?=?latitude;??
  • }??
  • ??
  • /**??
  • ?*?Returns?the?longitude?of?this?fix.??
  • ?*/??
  • public?double?getLongitude()?{??
  • ????return?mLongitude;??
  • }??
  • ??
  • /**??
  • ?*?Sets?the?longitude?of?this?fix.??
  • ?*/??
  • public?void?setLongitude(double?longitude){??
  • ????mLongitude?=?longitude;??
  • }??
  • mLocation.setLatitude(latitude);函數就會把

    mLatitude= latitude;

    然后,應用層只要getLatitude()就知道了緯度了。

    其他的函數接口類似。

    簡單看下下面的一段應用層的代碼

    功能:展示GPS信息

    [html]?view plaincopy
  • private?void?updateToNewLocation(Locationlocation)??
  • ???{???????
  • ???
  • ?????if?(location?!=?null)??
  • ?????{???????????
  • ??????bear?=?location.getBearing();?//偏離正北方的度數??
  • ??????double?latitude?=location.getLatitude();??????//維度??
  • ??????double?longitude=location.getLongitude();?????//經度??
  • ??????double?GpsSpeed?=?location.getSpeed();?//速度??
  • ??????long?GpsTime?=?location.getTime();?//時間??
  • ??????Date?date?=?new?Date(GpsTime);??
  • ??????DateFormat?df?=?newSimpleDateFormat("yyyy-MM-dd?HH:mm:ss");??
  • ???????
  • ??????float?GpsAlt?=(float)location.getAltitude();??//海拔??
  • ??????latitudeview.setText(""?+latitude);??
  • ??????longitudeview.setText(""?+longitude);??
  • ??????speedview.setText(""+GpsSpeed);??
  • ?????timeview.setText(""+df.format(date));??
  • ?????altitudeview.setText(""+GpsAlt);??
  • ??????bearingview.setText(""+bear);??
  • ??????}??
  • ??????else??
  • ??????{?????
  • ???????Toast.makeText(this,?"無法獲取地理信息",?Toast.LENGTH_SHORT).show();??
  • ??????}??
  • ???
  • }??
  • 終于,從衛星信號到android APP層獲取到數據那個簡單的數據流程分析好了。要想更加細致的了解其機制,還是得需要花更多的時間繼續深入下去的。其中還有很多的細節,很多概念都不是很明白。只知道個大概。不過通過這次分析,收獲不少。凡事都需要從整體到部分再到整理,從整理的GPS框架,到分成很多塊理解,再把那些模塊整合在一起,從而了解其整個機制。

    總結

    以上是生活随笔為你收集整理的和菜鸟一起学android4.0.3源码之硬件gps简单移植【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    精品久久久久久一区二区里番 | 日韩免费一区二区在线观看 | 在线视频 一区二区 | 97精品国产91久久久久久久 | 日韩在线观看中文 | 日韩精品中文字幕在线 | 99久久精 | 黄色一二级片 | 美女福利视频一区二区 | 777久久久 | 玖操| 日韩中文字幕免费电影 | 日产乱码一二三区别免费 | 黄色免费网 | 91桃色免费观看 | 一区二区三区四区在线免费观看 | 在线日韩精品视频 | 色综合久久久久久久久五月 | 日韩精品一区二区免费 | av在线在线 | 欧美另类交在线观看 | 美女视频免费一区二区 | 四虎国产精品免费观看视频优播 | 天天爽网站 | 亚洲在线色 | 又长又大又黑又粗欧美 | 久久1电影院 | 国产精品免费在线观看视频 | 国产精品久久久久永久免费 | 国产一区二区在线播放视频 | 欧美午夜视频在线 | 91亚色免费视频 | 中文字幕电影一区 | 国产精品美女久久久久久免费 | 国产成人精品亚洲日本在线观看 | 国产91精品高清一区二区三区 | 久久伦理电影网 | 干干操操 | 色伊人网 | 欧美激情视频在线观看免费 | 五月天最新网址 | 69精品视频在线观看 | 中文字幕日韩免费视频 | 国产精品美女在线 | 国产不卡av在线 | 91亚洲精品久久久久图片蜜桃 | 免费看v片网站 | 手机色站 | 天天操夜夜曰 | 色天堂在线视频 | 草久视频在线观看 | 欧美一区日韩精品 | 亚洲欧洲成人精品av97 | 成人在线视频免费看 | 国产精品美女久久久久久久 | 成人午夜电影免费在线观看 | 久久综合毛片 | 成人av在线电影 | 日本护士三级少妇三级999 | 天天色宗合 | 97综合在线 | 国产精品久久久久毛片大屁完整版 | 日韩免 | 久久精久久精 | 日本黄色片一区二区 | 青青河边草免费视频 | 日韩电影在线视频 | 日韩一区二区三区免费视频 | 欧美福利片在线观看 | 91精品国产福利 | 日本高清中文字幕有码在线 | 亚洲欧美偷拍另类 | 在线成人性视频 | 国产一区二区视频在线播放 | 午夜免费福利片 | 婷婷色五 | 久久论理 | 成人黄色电影在线播放 | 97精品国产97久久久久久久久久久久 | 91在线精品一区二区 | 国产精品9999久久久久仙踪林 | 在线观看一区视频 | 精品字幕 | 黄色av网站在线观看免费 | 亚洲精品色婷婷 | 91久久国产综合精品女同国语 | 中文字幕国产在线 | 天天色天天操综合网 | 99久热在线精品视频观看 | 欧美日韩在线视频一区二区 | 色久av | 99精品乱码国产在线观看 | 国产高清精| 国产美女被啪进深处喷白浆视频 | 精品中文字幕在线观看 | 91麻豆免费视频 | 日日干夜夜骑 | 亚洲精品国产精品久久99热 | 91麻豆网| 日日日日 | 天天操天天操天天干 | 香蕉在线观看视频 | 国产人成一区二区三区影院 | 欧美韩日在线 | 超碰97久久 | 91大神视频网站 | 一区二区视频播放 | 天堂av在线中文在线 | 国产999 | 国产亚洲人成网站在线观看 | 国产手机在线播放 | 久久久香蕉视频 | 久久久亚洲精品 | 国产精品免费一区二区 | 国产亚洲视频中文字幕视频 | 久久一级电影 | 波多野结衣在线视频一区 | 国产精品99久久久久久人免费 | 色亚洲激情 | 97国产大学生情侣酒店的特点 | 在线国产91| 日韩系列在线 | 日批网站免费观看 | 亚洲国产精品va在线看 | 久久五月精品 | 国产日韩高清在线 | 国产在线视频一区二区 | 青青草久草在线 | 精品在线观看一区二区三区 | 国产一二三区av | 特级a老妇做爰全过程 | av 一区二区三区 | 综合网婷婷| 成人免费视频观看 | 一级黄色网址 | 97狠狠干| 国产精品视频在线观看 | 日日干日日操 | 天天操天天色综合 | 久久免费播放 | www.神马久久 | 欧美一级特黄高清视频 | 日韩精品久久久久久久电影99爱 | 三级在线视频播放 | 日韩在线视频国产 | 免费在线国产黄色 | 中文av网| 国产91精品久久久久 | 久久歪歪| 27xxoo无遮挡动态视频 | 精品亚洲国产视频 | 久久天天躁狠狠躁亚洲综合公司 | 精品中文字幕在线播放 | 精品视频在线播放 | 天天爱av导航| 日韩在线观看视频一区二区三区 | 国产精品毛片久久久久久久久久99999999 | www.日本色 | 区一区二区三在线观看 | 日韩专区在线观看 | 亚洲视频一区二区三区在线观看 | 国产精品18毛片一区二区 | 天天草天天干天天射 | 在线观看精品 | 精品久久久久免费极品大片 | 91专区在线观看 | 在线观看av小说 | 久久精彩 | 天堂在线视频免费观看 | 亚洲成人影音 | 欧美激情精品久久久久久免费印度 | 在线直播av | 极品久久久久 | 黄色av网站在线观看免费 | 伊人色播| 日韩理论片在线 | 在线成人免费av | 精品视频区 | 国产不卡视频 | 亚洲精品字幕 | 国产精品igao视频网入口 | 色噜噜在线观看 | 激情网第四色 | 色999精品 | 999精品网| 中文字幕亚洲字幕 | 青青河边草免费视频 | 国产精品va | 成人毛片网 | 国产亚洲永久域名 | 黄色亚洲大片免费在线观看 | 波多野结衣一区二区 | 亚洲免费国产 | 热久久电影 | 久草久草在线 | 国产99久久久精品视频 | 91看片淫黄大片在线播放 | 免费av影视| 欧美美女视频在线观看 | 国色天香av | 天堂网一区二区 | 五月婷色 | 欧美福利在线播放 | 国内精品毛片 | 久久久免费观看完整版 | 亚洲v欧美v国产v在线观看 | 波多野结衣视频一区二区三区 | 麻豆传媒视频在线 | 久久久久久久网站 | 天堂久色 | 在线观看的黄色 | 青青草久草在线 | 精品一区二区综合 | 色视频国产直接看 | 日韩av五月天 | 国产精品视频永久免费播放 | av电影在线观看 | 国产成人综合精品 | 免费色黄 | mm1313亚洲精品国产 | 中文字幕av专区 | 日韩欧美在线观看一区 | 免费看的黄色网 | 久久视频在线观看免费 | 中文字幕一区二区三区四区 | 亚州精品天堂中文字幕 | 久久久九九 | 亚洲精品一区二区久 | 99麻豆久久久国产精品免费 | 久久久久久久久久久电影 | 美州a亚洲一视本频v色道 | 成人免费看片98欧美 | 欧美一级大片在线观看 | 精品夜夜嗨av一区二区三区 | 午夜视频在线观看一区 | 在线观看蜜桃视频 | 在线激情av电影 | 久久线视频 | 韩国视频一区二区三区 | av成人免费在线观看 | 五月综合激情网 | 成人在线免费看视频 | 天天综合网~永久入口 | 日韩视频精品在线 | 日韩大片在线观看 | 亚洲免费不卡 | 色婷婷综合久久久中文字幕 | 国产精品白浆视频 | 久青草视频 | 伊人五月婷 | 国产午夜在线观看视频 | 伊人成人精品 | 久草在线免费资源 | www.操.com| 91精品综合在线观看 | 综合久久久久 | 一区二区中文字幕在线播放 | 国产91欧美 | 久久精品国产精品亚洲 | 国产在线va| 国产剧情一区二区 | 狠狠色丁香久久婷婷综合丁香 | 日韩一区视频在线 | 久久精品久久99精品久久 | 亚洲国内精品视频 | 色偷偷男人的天堂av | 久久99精品国产一区二区三区 | 中文在线8资源库 | 欧美一级大片在线观看 | 日韩视频 一区 | 欧美精品成人在线 | 日韩有码在线观看视频 | 久久视频免费在线观看 | 亚洲一区视频免费观看 | 国产麻豆电影在线观看 | 久草在线电影网 | 日韩啪啪小视频 | 五月激情久久久 | 国产最新视频在线 | 亚洲综合欧美日韩狠狠色 | 久久久在线免费观看 | 免费a视频| 黄色性av| 成年人视频在线 | 久久久人人爽 | 免费黄色网止 | 99色在线播放 | 黄色免费网 | 欧美一级片在线观看视频 | 人人干狠狠操 | 天天操天天曰 | 国产免费美女 | 亚洲免费精品视频 | 天天综合久久综合 | 国产精久久 | 91一区啪爱嗯打偷拍欧美 | 成人免费看片98欧美 | 在线视频 国产 日韩 | 色综合中文字幕 | 手机看国产毛片 | 中文字幕乱视频 | 国产精品久久久久久久久久久久午夜 | 日本中文字幕电影在线免费观看 | 精品uu| 久久国产精品免费看 | 国产综合香蕉五月婷在线 | 日韩欧美在线不卡 | 国产精品免费久久久久久久久久中文 | 国产精品精品 | 麻豆国产精品va在线观看不卡 | 中文字幕在线观看完整版 | 天天操夜夜想 | 久久精品国产一区 | 91丨九色丨国产在线观看 | 国产成人黄色 | 精品国产乱码久久久久久1区二区 | 美女视频黄在线 | 色综合www | 午夜黄色影院 | 中文字幕在线免费看线人 | 久久精品毛片基地 | 日本女人的性生活视频 | 国产精品一区二区你懂的 | 粉嫩av一区二区三区免费 | 欧洲精品码一区二区三区免费看 | 日本爽妇网 | 婷婷激情五月 | 亚州性色 | 黄色一级在线视频 | 国产青青青 | 免费久久久久久 | 99久久精品网 | 超碰在线最新地址 | www.日日操.com| 日本中文在线 | 在线观看色网站 | 亚洲精品美女久久 | 1000部国产精品成人观看 | 成人不用播放器 | 特级毛片aaa | 在线观看成人一级片 | 伊甸园永久入口www 99热 精品在线 | 91久久精品一区二区三区 | 九九久久久| 欧美在线a视频 | 81国产精品久久久久久久久久 | 日日夜夜网站 | 国产又黄又爽又猛视频日本 | 日日狠狠 | 2020天天干天天操 | 午夜精品久久久久久久99热影院 | 免费精品 | 精品一区二三区 | 久久精品欧美一 | 欧美精品v国产精品v日韩精品 | 久久免费视频国产 | 亚洲专区在线播放 | 国产麻豆剧传媒免费观看 | 日韩欧美视频一区二区三区 | 亚洲乱码精品久久久 | 国产一区二区三区久久久 | 国产高清永久免费 | 蜜臀av一区二区 | 亚洲免费观看视频 | 国产精品中文久久久久久久 | 久久av高清| 在线观看不卡视频 | 色av色av色av| 91麻豆精品国产午夜天堂 | 麻豆国产精品一区二区三区 | 免费三级在线 | 中文字幕在线免费看线人 | 欧美综合在线观看 | av高清免费| 午夜色婷婷 | 中文字幕一区二区三区四区在线视频 | 最新中文字幕在线播放 | 91日韩精品 | 一区 在线 影院 | 精品久久久免费 | 国产精品乱码久久久久 | 免费av看片 | 午夜在线观看一区 | 日韩精品一区二区三区视频播放 | 91精品久久久久久综合乱菊 | 亚洲丝袜一区二区 | 久久精品视频国产 | 精品综合久久 | 亚州性色 | 久久经典国产视频 | 久久资源在线 | 日韩视频图片 | 2020天天干天天操 | 成人亚洲网 | 欧美日韩国产精品爽爽 | 91在线视频免费播放 | 激情综合五月 | 国产一区二区精品在线 | 97香蕉超级碰碰久久免费软件 | 久久精品4 | 91视频亚洲| 国产精品免费麻豆入口 | 美女激情影院 | 手机看国产毛片 | 97av影院| 亚洲 欧美 国产 va在线影院 | 中文字幕网站 | 久久久精品综合 | 久久久久亚洲最大xxxx | 四虎天堂 | 国产剧情一区二区在线观看 | 国产精品黄网站在线观看 | 九九免费在线看完整版 | 中文字幕在线免费播放 | 五月综合婷 | 欧美精品久久久久久久久久 | 麻豆视频免费播放 | 狠狠色狠狠色综合日日92 | 在线小视频 | 欧美少妇影院 | 天天激情天天干 | 丝袜av网站| 少妇bbb好爽 | av韩国在线 | 免费在线观看视频一区 | 欧美日韩另类在线 | 久草在线播放视频 | 亚洲精品美女在线 | 久久国产乱 | 99久热在线精品 | 激情欧美一区二区三区 | 黄色三级免费看 | 久久精品国产第一区二区三区 | 亚洲电影久久久 | 99免费在线视频观看 | 国产成人免费观看久久久 | 亚洲激情视频在线观看 | 在线免费av播放 | 日韩视频中文字幕在线观看 | 国产精品美女久久久久久久久 | 国产一二区免费视频 | 亚洲伦理一区二区 | 日韩视频精品在线 | 国产99久久久精品 | 在线视频电影 | 国产精品自产拍 | 99视频在线免费看 | 久久综合偷偷噜噜噜色 | 91桃色国产在线播放 | 91黄色视屏 | 伊人久久国产精品 | 亚洲理论在线 | 99视频免费| 狠狠干免费 | 啪啪动态视频 | 五月婷婷在线观看视频 | 亚洲国产丝袜在线观看 | 精品视频成人 | 日日干 天天干 | 国产在线视频导航 | 国产视频18| 久久久男人的天堂 | 波多野结衣久久精品 | 天天射,天天干 | 综合久久网站 | 伊人午夜| 91精品一区二区在线观看 | 欧美日韩观看 | 最新国产精品久久精品 | 亚洲国产欧美在线看片xxoo | 91免费版在线 | 日韩在线免费看 | 草久热 | 亚洲成人黄色在线观看 | 久久系列 | 欧亚久久| 日韩久久一区 | 精品91在线 | 日本激情视频中文字幕 | 国产免费美女 | 少妇自拍av | 亚洲精品女人久久久 | 国产欧美精品xxxx另类 | 久久久视屏 | av一级在线 | av在线收看 | 97国产大学生情侣白嫩酒店 | 国产短视频在线播放 | av三级在线播放 | 伊人五月天av | 91看片在线 | 综合网伊人 | a级国产乱理伦片在线观看 亚洲3级 | 四虎永久精品在线 | 日韩在线第一区 | 99热高清 | 黄色三级免费观看 | 国产亚洲精品精品精品 | 日韩av区 | 天天做日日做天天爽视频免费 | 久久国产网 | 超碰免费av | 久久成人国产精品 | 日本婷婷色 | 色香天天 | 超碰最新网址 | 激情丁香综合五月 | 激情网综合 | 久久不射电影院 | 91高清在线 | 日本视频网 | 美女视频黄在线 | 欧美日韩一区二区免费在线观看 | 国产成人精品在线播放 | 国产美女久久久 | 成人在线免费看视频 | 婷婷激情五月综合 | 免费一级毛毛片 | 精品视频区 | av片中文字幕 | 欧美国产日韩一区二区三区 | 亚洲精品视频在线观看网站 | 久久精品资源 | 久久综合天天 | 正在播放国产91 | 黄色三级网站在线观看 | 99久热在线精品视频观看 | 奇米影音四色 | 日韩一二区在线 | 欧美日韩69| 99视频免费在线观看 | 夜添久久精品亚洲国产精品 | 国产精品wwwwww | 91高清在线| 久久伊人综合 | 国产精品激情 | 久久综合五月婷婷 | 九9热这里真品2 | 亚洲欧美日韩国产一区二区三区 | 99热999| 国产精品高清在线观看 | 天天透天天插 | 麻豆视频在线播放 | 天天操夜夜逼 | 九月婷婷色 | 亚洲高清资源 | 国产成人精品一区二区在线观看 | 国产亚州精品视频 | 久久国产三级 | 欧美日韩亚洲在线观看 | 天天夜夜亚洲 | 久久国产精品色av免费看 | 久久精品99国产精品 | 黄色在线免费观看网址 | 99国产在线 | 激情久久伊人 | 亚洲三级国产 | 日韩久久久久久 | 五月婷婷免费 | 国产视频久久久 | 五月天天在线 | 久久综合九色九九 | 国产成人久久精品一区二区三区 | 尤物一区二区三区 | 国产一级在线播放 | 黄色网www | 国产视频97 | 欧美日韩aa | 欧美性超爽 | av一级片在线观看 | 日本精品中文字幕在线观看 | 91视频三区 | 免费在线看成人av | 国产精品99久久久久久大便 | 91精品伦理 | 日韩欧美第二页 | 久久96国产精品久久99漫画 | 五月婷久| www免费看 | 国产视频中文字幕在线观看 | 天天噜天天色 | 色av男人的天堂免费在线 | 亚洲国产剧情av | 最近高清中文在线字幕在线观看 | 99精品国产高清在线观看 | 亚洲在线视频免费观看 | 国产破处在线播放 | 亚州日韩中文字幕 | 国产精品123 | 91超碰在线播放 | 激情久久影院 | 久久久久久免费毛片精品 | 欧美日韩一区二区久久 | 一区二区三区在线免费 | 99精品黄色片免费大全 | 色网站在线观看 | www免费看| 欧美视频在线观看免费网址 | 人人爽人人爽人人爽 | 日韩69视频 | 91大神dom调教在线观看 | 中日韩在线 | 日韩一二三区不卡 | 亚洲天天综合网 | 天天操天天谢 | 五月婷婷欧美视频 | 天天干天天操人体 | 五月婷婷毛片 | 国产中文字幕在线免费观看 | 欧美午夜寂寞影院 | 国内精品久久久久影院一蜜桃 | 成人黄色片免费 | av在线网站观看 | 国产一级电影免费观看 | av免费在线播放 | 黄色毛片视频免费观看中文 | 人人爽人人舔 | 成年人在线播放视频 | 男女日麻批 | 9在线观看免费高清完整版 玖玖爱免费视频 | av三级av| 中文字幕一区二区三区四区 | 成人国产电影在线观看 | 中文字幕在线视频一区二区三区 | www.久久久.com| 日韩精品一区二区三区在线播放 | 亚洲精品小视频在线观看 | 中文字幕二区在线观看 | 久久久亚洲电影 | 欧美日韩免费在线观看视频 | 香蕉影院在线 | 高清av免费看 | 国产中的精品av小宝探花 | 黄色大全在线观看 | 国产视频一区二区在线 | 国产小视频免费观看 | 国产女v资源在线观看 | av在线小说| 国产高清视频免费 | 一区免费观看 | 亚洲综合导航 | 激情网五月婷婷 | 国产99久久久国产精品免费二区 | 国产又粗又猛又爽又黄的视频免费 | 丁香综合五月 | 国产精品大尺度 | 免费在线观看av网址 | 五月婷婷六月综合 | 99久久精品午夜一区二区小说 | 成人性生爱a∨ | 成人免费观看在线视频 | 玖玖视频精品 | 国产中文字幕在线免费观看 | 九九九在线观看 | 99久久99精品| 国产尤物一区二区三区 | 可以免费观看的av片 | 国产精品毛片一区二区三区 | 日韩三级精品 | 亚洲2019精品 | 成人免费网站在线观看 | 国产精品美女久久久免费 | 制服丝袜亚洲 | 91看片一区二区三区 | 精品亚洲成a人在线观看 | 永久免费av在线播放 | 日日摸日日添夜夜爽97 | 日韩高清 一区 | 九九九热精品免费视频观看 | 美女免费视频观看网站 | 久操97| 久久伊人综合 | 偷拍区另类综合在线 | 国产综合在线观看视频 | 日三级在线 | 天天爱天天插 | 六月激情丁香 | 亚洲色视频| 美女视频黄频大全免费 | 日本中文一级片 | 日韩黄色中文字幕 | 免费在线电影网址大全 | 亚洲国产99 | 91在线麻豆 | 久久精品久久综合 | 日韩在线激情 | 国产免费久久av | 午夜三级理论 | 免费a视频在线观看 | 亚洲天天在线日亚洲洲精 | 99精品视频在线观看 | 中文字幕在线网 | 国产一区自拍视频 | 波多野结衣视频一区 | 中文字幕一区二区三区久久 | 国产在线观| 国产精品99久久久久久宅男 | 色资源二区在线视频 | 美女黄视频免费 | 欧美日韩不卡在线观看 | 激情五月色播五月 | 日韩狠狠操 | 国产在线观看中文字幕 | 国产成人精品久久久久 | 色婷婷精品 | 欧美一区日韩一区 | 国产亚洲精品女人久久久久久 | 精品免费视频. | 亚洲成人av片在线观看 | 婷婷丁香色综合狠狠色 | 中文字幕观看在线 | 中文超碰字幕 | 欧美日韩国产三级 | 在线观看av小说 | 伊人射 | 高清美女视频 | www.久久久.cum | 天天拍天天爽 | 狠狠色丁香久久婷婷综合丁香 | 99久热在线精品视频观看 | 色在线免费观看 | 欧美日一级片 | 亚洲欧美日韩一级 | av免费看av| 成人a级黄色片 | 日韩免费在线观看视频 | 狠狠插狠狠干 | 日韩最新在线 | 日本女人的性生活视频 | 久久夜av | av 在线观看 | 一区二区三区 中文字幕 | 在线你懂的视频 | 99视频在线精品免费观看2 | 五月天色站| 亚洲成人精品久久久 | 国产精品久久久久一区二区国产 | 欧美日韩一区二区久久 | 久久最新| 国产免费又粗又猛又爽 | 在线黄色观看 | 一区二区日韩av | 成人黄色毛片视频 | 日韩深夜在线观看 | 亚洲美女精品区人人人人 | 天天添夜夜操 | 久久影院一区 | 久久久网页 | 国产91亚洲 | 久久福利剧场 | 久久精品一区二区三区中文字幕 | 久久久国产网站 | 曰本免费av | 国产高清视频色在线www | 日韩电影一区二区在线观看 | 最近乱久中文字幕 | 久久国产精品影视 | 欧美激情精品久久久久 | 97电影在线看视频 | 米奇狠狠狠888 | 天天操天天干天天爽 | 97超在线视频 | 成人免费网视频 | 久草在线一免费新视频 | 在线播放你懂 | 久久免费视频国产 | 91九色蝌蚪国产 | 天天操夜夜曰 | 黄色av电影在线 | 国产精品久久久久久久免费观看 | 久久久久在线观看 | 日韩av快播电影网 | 久久久久久久久久免费视频 | 国产一区二区在线免费播放 | 国产免费a | 999久久久国产精品 高清av免费观看 | 狠狠躁夜夜a产精品视频 | 国产剧情一区 | 国产精品福利在线观看 | 日日夜夜操av | 欧美色道| 久久视频二区 | 久日精品 | 国产丝袜一区二区三区 | 99热在线精品观看 | 中文字幕日本在线观看 | 午夜av一区| 五月婷婷激情六月 | 国产一二区在线观看 | 日韩99热| 午夜手机电影 | 丁香六月欧美 | 99视频在线精品免费观看2 | 在线观看免费av片 | 亚洲精品综合在线 | 在线观看中文字幕第一页 | 韩日av一区二区 | 亚洲最大av在线播放 | 日本久久精品视频 | 久99久精品视频免费观看 | 亚洲综合色视频在线观看 | av超碰在线| 综合精品久久久 | 97超视频免费观看 | 97网| 亚洲资源网| 日韩精品一区在线播放 | 97天天干 | 男女全黄一级一级高潮免费看 | 成人国产精品久久久久久亚洲 | 国产在线中文 | 99国产在线观看 | 69国产盗摄一区二区三区五区 | 久久久久综合精品福利啪啪 | 丁香一区二区 | 国产 精品 资源 | 四虎欧美| 欧美一级高清片 | 国产无遮挡又黄又爽在线观看 | 成人永久在线 | 国产91大片| 国产精品毛片一区二区 | 婷婷精品国产欧美精品亚洲人人爽 | 久久免费国产精品 | 热久久最新地址 | 久久久久免费网站 | 日韩欧美电影在线观看 | 丁香六月天婷婷 | 国产一二三区在线观看 | 在线草 | 久久久久久久99精品免费观看 | 日韩网站在线看片你懂的 | 少妇搡bbbb搡bbb搡69 | 91精品国产九九九久久久亚洲 | 在线免费黄色毛片 | 国产录像在线观看 | 欧美色就是色 | 国产资源在线免费观看 | 欧美日韩在线视频一区 | 久久国产电影院 | 色婷婷www | 在线成人欧美 | 黄色软件在线看 | 国产精品白浆视频 | 永久黄网站色视频免费观看w | 亚洲 欧美 变态 国产 另类 | 久久天天躁狠狠躁亚洲综合公司 | 国产免费又黄又爽 | 欧美色图另类 | 一区二区三区免费网站 | 91麻豆精品91久久久久同性 | 免费又黄又爽 | 亚洲成人二区 | 成人羞羞视频在线观看免费 | 国产自偷自拍 | 91成人在线观看喷潮 | 久久久久久久久久网站 | 久久精品看片 | 欧美日韩中文字幕综合视频 | 亚洲乱码在线观看 | 国产色 在线 | 国内久久精品视频 | 国产高潮久久 | 久久香蕉国产精品麻豆粉嫩av | 亚洲六月丁香色婷婷综合久久 | 精品亚洲午夜久久久久91 | 国产精品免费小视频 | 美女久久网站 | 国产又粗又猛又黄又爽 | 色婷av| 91麻豆看国产在线紧急地址 | av 一区二区三区 | 国产福利91精品一区二区三区 | 成人夜晚看av | 欧美少妇xxxxxx | 缴情综合网五月天 | 激情视频二区 | 精品久久免费看 | 超碰国产在线播放 | 成人久久影院 | 亚洲成人精品在线 | 国产毛片aaa| 日本中文乱码卡一卡二新区 | 91中文字幕在线 | 天天操天天射天天爱 | av色一区 | 久久久在线视频 | 欧美精品做受xxx性少妇 | 久久热首页 | 天堂av网站| 久久99精品国产 | av观看在线观看 | 四虎影视成人永久免费观看亚洲欧美 | 在线免费观看羞羞视频 | 久久黄色免费观看 | 亚洲在线视频观看 | 国产香蕉视频在线播放 | 99久久国产免费,99久久国产免费大片 | 婷婷综合视频 | 成人av免费在线 | 婷婷丁香激情网 | 国精产品一二三线999 | 91亚洲精品国偷拍 | 欧美亚洲一区二区在线 | 成人欧美一区二区三区在线观看 | 中文字幕电影高清在线观看 | 免费在线看v | 伊人资源站 | 久久免费福利 | 日日夜夜精品网站 | 国产一二三区在线观看 | 狠狠干成人综合网 | 久久久久亚洲天堂 | 青青河边草观看完整版高清 | 91九色视频网站 | 色综合色综合久久综合频道88 | av免费电影在线 | 黄色免费网战 | 少妇精品久久久一区二区免费 | 国产很黄很色的视频 | 欧美a性 | 香蕉97视频观看在线观看 | 亚洲伦理一区二区 | 97碰碰视频| 丁香资源影视免费观看 | 一级黄色片毛片 | 92中文资源在线 | 六月丁香激情综合 | 国产精品久久久久久69 | 色婷婷在线视频 | 久久无码精品一区二区三区 | 亚洲国产中文字幕在线观看 | 免费a级黄色毛片 | 国产小视频在线免费观看 | 久久精品导航 | 婷婷成人亚洲综合国产xv88 | 麻豆视频观看 | 国产色女 | 欧美精品三级在线观看 | 国产在线免费观看 | 日本字幕网 | 国产精品久久久久久久久久久久午夜 | 在线观看a视频 | 久久成人毛片 | 中文字幕 国产精品 | 免费在线国产黄色 | www九九热| 99精品视频在线观看 | 色丁香久久 | 2023天天干 | 日韩欧美在线国产 | 国产精品久久久久久久av电影 | 国产91在线免费视频 | 免费中文字幕视频 | 四虎在线免费视频 | 探花视频在线版播放免费观看 | 黄av资源 | 日本三级吹潮在线 | 欧美精品久久久久久 | 欧美性色黄| 亚洲高清视频一区二区三区 | 福利网在线| 人人插人人搞 | 亚洲欧洲精品在线 | 天天干天天干天天干 | 久久婷婷视频 | 亚洲精品网站 | 国产无套精品久久久久久 | 国产日韩亚洲 | 欧美亚洲国产一卡 | 91亚洲精品久久久久图片蜜桃 | 成人一区二区三区中文字幕 | 成年人免费看片网站 | 超碰免费观看 | 九色自拍视频 | 天天综合久久综合 | 色综合天天综合 | 狠狠88综合久久久久综合网 | 一区二区三区视频 | 亚洲在线色 | 天天草天天色 | 五月婷婷六月丁香激情 | 国产一级黄色免费看 | 色狠狠久久av五月综合 | 人人插人人爱 | 精品国产人成亚洲区 | 国产精品久久久久久久久久久免费看 | 99视频在线观看一区三区 | 亚洲美女视频在线观看 | 精品一区欧美 | 午夜久久网| 美女搞黄国产视频网站 | 久久久男人的天堂 | 亚洲资源在线观看 | 日本丶国产丶欧美色综合 | 国产中的精品av小宝探花 | 麻豆久久久久 | 三级黄色免费片 |