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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

android GPS驱动

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android GPS驱动 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

android GPS驅動

?

關于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個不等,由接收機的類型而定??偟膩碇v,信號通道目前有相關型、平方型和相位型等三種。新一代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)?;钴S航線一般在設置 -> 航線菜單下設定。如果目前有活動航線,那么"導向"的點是航線中第一個路點,每到達一個路點后,自動指到下一個路點。

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?,F最新的模塊為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芯片?,F在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、其他函數,開啟導航,關閉導航等的就不一一介紹了,和上面的類似??梢钥丛创a。

    好了,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框架,到分成很多塊理解,再把那些模塊整合在一起,從而了解其整個機制。

    總結

    以上是生活随笔為你收集整理的android GPS驱动的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    免费看久久| 美女免费视频一区 | 国产午夜精品久久 | 亚洲精品国产成人av在线 | 97电影网手机版 | 午夜精品久久久久久久99热影院 | 国产91精品欧美 | 丁香婷婷综合激情五月色 | 免费看成人a| 国产在线专区 | 日韩免费在线观看 | 久久久免费看片 | 欧美激情视频免费看 | 久久夜色精品国产欧美乱 | 正在播放久久 | 国产精品久久嫩一区二区免费 | 99re国产视频| 在线观看深夜视频 | 在线看成人片 | 97色在线| 欧美另类美少妇69xxxx | 日日日日 | 成人在线观看你懂的 | 国产精品视频永久免费播放 | 国产一二区视频 | 精品一区二区在线免费观看 | 天天做天天爱天天爽综合网 | 国产精品一区二区美女视频免费看 | 午夜黄网 | 亚洲最大av在线播放 | av综合av | 亚洲黄色免费电影 | 欧美成年性 | 亚洲精品在线观看av | 99精品视频在线播放观看 | 狠狠婷婷 | 亚洲精品视频一二三 | 亚洲美女精品 | 国产亚洲精品美女 | 日日操天天爽 | 日本mv大片欧洲mv大片 | 99久久综合狠狠综合久久 | 精品国产美女 | 中文字幕免费观看全部电影 | 国产精品com | 国产 亚洲 欧美 在线 | 碰碰影院 | 91精品1区 | 久久黄色小说视频 | 天天操天天干天天爱 | 欧美孕交vivoestv另类 | 欧洲精品码一区二区三区免费看 | 奇米7777狠狠狠琪琪视频 | 四虎影视8848aamm | 亚洲欧美色婷婷 | 97夜夜澡人人双人人人喊 | 波多野结衣视频网址 | 热久久国产精品 | 国产精品久久久久久久久岛 | 在线观看成人国产 | 亚洲精品视频在线 | 在线观看国产亚洲 | 久久99免费视频 | 久草免费新视频 | 成人在线一区二区 | 91av色| 久久亚洲私人国产精品 | 视频在线亚洲 | 久久综合九色综合久99 | 国产大陆亚洲精品国产 | 成人国产精品久久久 | 99精品小视频 | 青青河边草免费视频 | 亚洲在线视频观看 | 色网免费观看 | 国产精品视频免费观看 | 在线国产视频 | 日韩久久久久久 | 精品国产综合区久久久久久 | 不卡视频在线看 | 久久久久久久久影院 | 久久人人精品 | 成人欧美一区二区三区在线观看 | 人人爽人人爽人人片av免 | 婷婷综合在线 | av日韩av | 夜夜操综合网 | 日韩中文字幕免费在线观看 | 依人成人综合网 | 国产男女爽爽爽免费视频 | 精品专区| 99视频国产精品免费观看 | 69国产在线观看 | 免费看三级黄色片 | 中文字幕一区二区三区在线播放 | 玖玖玖精品 | 91高清免费看 | 久久久久久久久久影院 | 激情婷婷丁香 | 天天操一操 | 激情婷婷丁香 | 日韩av伦理片 | 在线免费观看黄网站 | 人人狠| 国产一区二区三区免费在线 | 久久精品人人做人人综合老师 | 成人在线视频免费 | 2023国产精品自产拍在线观看 | 中文字幕av网站 | 亚洲成年人免费网站 | 国产精品美女毛片真酒店 | 免费高清在线视频一区· | 天天性天天草 | 亚洲精品国产品国语在线 | 性色av免费观看 | 国产精品久久久久永久免费观看 | 天堂视频中文在线 | 五月婷婷黄色 | 中文在线亚洲 | 国产精品一区二区三区久久 | www.一区二区三区 | 国产精品69av | 精品一二三区视频 | 99人成在线观看视频 | 综合精品久久 | 久久国产精品久久久久 | 久久久久一区二区三区四区 | 一区二区三区www | 国产99久久九九精品 | 欧美激情视频一区二区三区 | 国产又粗又长又硬免费视频 | av在线网站免费观看 | 久久黄色成人 | 天天做天天爱夜夜爽 | 中文字幕在线观看视频网站 | 久久久精品国产一区二区三区 | 精品视频中文字幕 | av在线亚洲天堂 | 在线亚洲人成电影网站色www | 三级黄色在线 | 91精品蜜桃 | 婷婷日日 | 色偷偷中文字幕 | 婷婷丁香七月 | 午夜精品一区二区三区在线播放 | 亚洲黄色av网址 | 麻豆久久一区二区 | 亚洲免费永久精品国产 | 精品久久福利 | 久久久999精品视频 国产美女免费观看 | 亚洲小视频在线观看 | 日韩高清免费在线 | 夜夜躁狠狠躁 | 一区二区三区电影 | 久久视频免费看 | 精品国产三级 | 国产精品成人一区二区 | 射射射综合网 | 国偷自产视频一区二区久 | 中文在线字幕免 | 毛片久久久 | 黄色av电影 | 久草网站| 热re99久久精品国产66热 | 中文字幕刺激在线 | 日韩av一区二区在线播放 | 日韩精品不卡在线观看 | 成人av在线亚洲 | 欧美一区二区三区四区夜夜大片 | 伊人久久精品久久亚洲一区 | 国产精品12345| 狠狠躁日日躁夜夜躁av | 四虎影视成人精品 | 97人人射| 男女免费视频观看 | 久久国产免费看 | 欧美最猛性xxx | 一区二区三区在线不卡 | 免费看片色 | 人成在线免费视频 | 97超碰人人在线 | www最近高清中文国语在线观看 | 天天拍天天干 | 久久久久久免费毛片精品 | 99热九九这里只有精品10 | 久久久在线视频 | 久久精品美女视频 | 日韩视频一区二区三区在线播放免费观看 | 少妇av片 | 成年一级片 | 五月婷婷伊人网 | 五月天视频网 | 国产精品一级视频 | 亚洲免费在线播放视频 | 天天综合色 | 亚洲成人国产精品 | 日韩中文在线电影 | 成人福利在线播放 | 国产高清视频网 | 精品国产伦一区二区三区观看说明 | 日韩在线观看一区二区 | 亚洲专区免费观看 | 亚洲精选久久 | 亚洲久草在线 | 丁香婷婷综合激情五月色 | 久久久久久久久久亚洲精品 | 草久久久| 日本3级在线观看 | 色婷婷六月天 | 在线黄色av | 国产亚洲视频在线观看 | 91视频在线自拍 | 丝袜美女在线 | 伊人网综合在线观看 | 久久久久久国产精品亚洲78 | 欧美性爽爽 | 特级西西人体444是什么意思 | 精品在线视频一区 | 成人在线播放免费观看 | 久久久久久久国产精品视频 | 狠狠色综合欧美激情 | 欧美最猛性xxxxx亚洲精品 | 欧美乱熟臀69xxxxxx | 不卡精品 | 91精品在线免费 | 亚洲五月综合 | 在线观看岛国 | 中午字幕在线观看 | 在线国产能看的 | 欧美日韩中文视频 | 精品国产黄色片 | 日日爱网址| 国内精品久久久久影院优 | 丰满少妇对白在线偷拍 | 中文字幕在线久一本久 | 国产一级二级在线观看 | 国产成人一区二区三区 | 国产精品入口66mio女同 | 99久国产 | 日韩剧 | 欧美成人va| 国产在线一区二区 | www.com.日本一级 | 久久精品男人的天堂 | av九九 | 黄色日视频 | 91探花国产综合在线精品 | 久久国产精品99久久久久久老狼 | 97av精品| 国产不卡一区二区视频 | 国产一级片免费观看 | 亚洲一级片在线观看 | 911久久| 91精品视频免费观看 | 丰满少妇高潮在线观看 | 国产综合视频在线观看 | 午夜精品久久久久久久久久久 | 狠狠干天天操 | 国产精品一区二区三区在线看 | 一区二区不卡高清 | 成人毛片100免费观看 | 精品五月天 | 美女视频黄网站 | 国产美腿白丝袜足在线av | 丁香六月久久综合狠狠色 | www夜夜操 | 亚洲经典在线 | 久久午夜鲁丝片 | 69国产精品成人在线播放 | 又黄又爽又湿又无遮挡的在线视频 | 日韩欧美在线观看 | 911香蕉 | 黄色毛片视频免费观看中文 | 美女视频黄免费的久久 | 黄色毛片在线看 | 免费看片黄色 | 国产精品av免费在线观看 | 91九色蝌蚪视频网站 | 91成人看片| 中文字幕精品www乱入免费视频 | 日韩在线网址 | 99re久久资源最新地址 | 在线免费观看视频你懂的 | 免费韩国av | 日本激情视频中文字幕 | 99精品视频中文字幕 | 久久久免费观看完整版 | 91成人免费观看视频 | 99999精品视频| 久草在线视频中文 | 亚洲精品久久视频 | 色射色| 97在线观看免费 | 香蕉97视频观看在线观看 | 少妇bbb搡bbbb搡bbbb | 午夜成人影视 | 久久久久福利视频 | 久久免费看av | 91视频这里只有精品 | 视频国产精品 | 8090yy亚洲精品久久 | 国产精品久久久久久久久久久久 | 婷婷去俺也去六月色 | 婷婷网在线 | 99在线观看免费视频精品观看 | 96精品视频 | 91精品久久久久久久久久久久久 | 激情婷婷综合网 | 麻豆国产精品一区二区三区 | 特级毛片爽www免费版 | 天天爱天天操 | 激情五月综合网 | 97色综合 | 国产福利在线免费 | 一级a性色生活片久久毛片波多野 | 在线视频一区二区 | 2021国产精品视频 | 欧美天天综合 | 国产三级午夜理伦三级 | 欧美精品第一 | 99久久9 | 午夜黄网| 亚洲女欲精品久久久久久久18 | 亚洲精品乱码白浆高清久久久久久 | 国产黄色av网站 | 久久久精品成人 | 欧美在线观看视频免费 | 亚洲高清视频在线播放 | www.夜夜操.com| 成年人看片| 日本中文一级片 | 视频一区二区视频 | 色婷婷国产 | 亚洲国产理论片 | 国产在线观看 | 狠色狠色综合久久 | 欧美国产91 | 亚洲三级精品 | 国产视频精品久久 | 国产剧情一区在线 | 亚洲人人av | 国产精品美女久久久久久久网站 | 麻豆影视在线免费观看 | 亚洲狠狠操 | 日本深夜福利视频 | 97香蕉久久国产在线观看 | 九九热免费在线观看 | 九九一级片 | 91成人网页版 | 日本黄色大片免费看 | 国产第一页在线播放 | av一区在线播放 | 超级碰碰碰碰 | 一本一道久久a久久精品 | 国产精品wwwwww | 久久少妇av| 国产 日韩 在线 亚洲 字幕 中文 | 99中文字幕视频 | 国产成人三级在线播放 | 久久精品国产精品亚洲 | 成年人电影毛片 | 8x成人免费视频 | 色婷婷a| 日韩一区二区三区观看 | 手机av电影在线 | 久久视频国产精品免费视频在线 | 午夜在线免费观看视频 | 黄色毛片在线看 | 国产麻豆果冻传媒在线观看 | 久久久精品日本 | 日日碰狠狠添天天爽超碰97久久 | 国产亚洲精品久久久久久移动网络 | 午夜久久美女 | 在线欧美小视频 | 天天爽天天摸 | 天天天天天天天操 | 久久综合精品国产一区二区三区 | 免费在线观看中文字幕 | 免费精品 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 欧美日韩视频在线播放 | 一区二精品 | 中文字幕在线有码 | 日韩天堂网 | 欧美一区二视频在线免费观看 | 久草久热 | 亚洲最大的av网站 | 亚洲精品男人天堂 | 国产成人不卡 | 在线观看91av | 日本 在线 视频 中文 有码 | 69久久99精品久久久久婷婷 | 九九九九九精品 | 亚洲高清视频一区二区三区 | 国产123区在线观看 国产精品麻豆91 | 亚洲 欧美 91 | www.com黄色| 欧美精品小视频 | 日韩欧美一区二区三区在线 | 中文字幕国语官网在线视频 | 五月天六月婷婷 | 久久精品99国产 | 在线天堂中文www视软件 | 欧美日韩精品区 | 在线观看国产一区二区 | 狠狠狠干 | 国产成人久久精品 | 日韩av电影网站在线观看 | 人人爽人人乐 | 久久久久麻豆 | 99精品一区二区三区 | 人人舔人人爱 | 亚洲精品免费在线视频 | 久久精品在线 | 91精品啪在线观看国产81旧版 | 日韩一区在线免费观看 | 日韩精品中文字幕久久臀 | 91在线播 | 91日韩精品一区 | 国产在线 一区二区三区 | 草久久影院 | 激情五月在线观看 | 国产一级性生活视频 | 999精品视频 | 久久久久 | 日本久久影视 | 亚洲综合激情五月 | 91色视频 | 国产不卡免费视频 | 伊人导航 | 成人av日韩| 成人在线播放视频 | 日韩中文字幕视频在线 | 亚洲天堂首页 | 国产在线更新 | 欧美日韩在线视频观看 | 色香蕉网 | 久久女同性恋中文字幕 | 久久免费视频播放 | 久久色在线播放 | 在线观看视频h | 亚洲综合色视频 | 国产手机精品视频 | 久久综合九色综合久久久精品综合 | 欧美精品久久久久久久久老牛影院 | 在线观看午夜 | 少妇搡bbbb搡bbb搡69 | 色综合天天综合 | 特片网久久| 精品国内自产拍在线观看视频 | 国产不卡在线观看视频 | 激情综合亚洲精品 | 99久久精品国产一区二区成人 | 免费在线精品视频 | 超级碰碰碰免费视频 | 狠狠的干狠狠的操 | 国产精品美乳一区二区免费 | 一区二区精品在线观看 | 久久久久久美女 | 在线之家官网 | 国产精品麻豆91 | 国产剧情一区二区 | 国产1级毛片 | 欧美另类激情 | 免费福利视频网站 | 天天干天天干天天操 | 国产精品毛片久久久久久久久久99999999 | 国产精品久久久久影院 | 天天干夜夜夜 | 九九交易行官网 | 久久国产一区二区 | 久久精品亚洲综合专区 | 丁香综合av| 欧美日bb | 色欧美综合 | 成人在线播放av | 日韩一级精品 | 久久精品这里精品 | 日本久久电影网 | 亚洲精品免费视频 | 欧美性网站 | 又湿又紧又大又爽a视频国产 | 亚洲综合网| 成人在线播放av | 欧美电影黄色 | 久久精品视频免费播放 | 色.com| 国产亚洲综合在线 | 免费在线观看av的网站 | 亚洲精欧美一区二区精品 | 在线国产91 | 欧美污网站| 在线黄色免费 | 国产精品一区一区三区 | 黄色在线看网站 | 国产不卡免费 | 亚洲精品免费视频 | 国产精品久久久久久久久久久免费看 | 午夜精品一二区 | 99热在线观看 | 成人动漫一区二区 | 日本久久精 | 香蕉视频18 | 2021国产在线 | 久久大片网站 | 日韩av手机在线观看 | 国产又粗又猛又黄又爽的视频 | 麻豆 91 在线| 免费进去里的视频 | 在线免费观看一区二区三区 | 中文字幕亚洲综合久久五月天色无吗'' | 国产成人亚洲精品自产在线 | 一区二区欧美激情 | 亚洲免费视频观看 | 精品久久久久久亚洲综合网站 | 伊人资源站 | 天天操综合网 | 天天操人 | 精品久久久久国产免费第一页 | 中文字幕一区二区三区四区 | 黄色片视频在线观看 | 一区二区三区四区五区在线视频 | 精品国产aⅴ一区二区三区 在线直播av | 天天天色综合a | 天无日天天操天天干 | 欧美9999| 美女在线国产 | 91精品国产一区二区三区 | 九九热只有精品 | 亚洲国产精品一区二区尤物区 | 亚洲成人免费在线 | 免费高清在线观看电视网站 | 天天爱天天干天天爽 | 久久久九色精品国产一区二区三区 | 亚洲最新av在线网址 | 在线观看www. | 激情av在线播放 | 17婷婷久久www| 激情影音先锋 | 丁香资源影视免费观看 | 日韩免| 久久免费试看 | 91正在播放 | 香蕉精品视频在线观看 | 天天操夜夜叫 | 激情网站免费观看 | 成人av影院在线观看 | 精品 一区 在线 | 精品国产成人 | 国产麻豆精品免费视频 | 久久亚洲福利 | 日韩激情视频 | 国产最新视频在线观看 | 91亚洲精品乱码久久久久久蜜桃 | 999亚洲国产996395| 视频在线99 | 97在线观看免费 | 2018好看的中文在线观看 | 欧美aaa视频 | 日韩欧美高清不卡 | 中文永久免费观看 | 91网在线看 | 国产九色在线播放九色 | 天天操天天射天天爱 | 99视频在线看 | 久久精品国产99国产 | 成年人视频在线 | 六月激情丁香 | 久久久免费看片 | 国产精品久久久久aaaa九色 | 欧美精品中文字幕亚洲专区 | 99精品视频在线观看视频 | 在线成人中文字幕 | 日韩久久久久久久 | 精品久久久久久久久久久久久久久久久久 | 国产97超碰| 久久在线电影 | 国产视频 亚洲精品 | 精品视频亚洲 | 久久福利 | 丁香婷婷色综合亚洲电影 | 精品福利视频在线 | 久久av一区二区三区亚洲 | 91av视屏| 精品在线一区二区 | 国产精品福利久久久 | 人人爽人人 | www亚洲精品 | 69视频网站 | 久久草在线免费 | 中文高清av| 五月婷婷在线播放 | 国产精品激情偷乱一区二区∴ | 国产亚洲va综合人人澡精品 | 久久久免费精品视频 | 91中文字幕在线播放 | 国产免费不卡av | 天天插天天射 | 亚洲最大成人网4388xx | 国产精品福利午夜在线观看 | 三级黄色在线观看 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 久久久久久美女 | 九九免费在线看完整版 | 天天干天天干天天干天天干天天干天天干 | 天天综合网 天天 | 又黄又刺激的视频 | 欧美激情第28页 | 女人18精品一区二区三区 | 免费久久久 | 久草视频在线免费播放 | 国产黄色免费看 | 亚洲热久久 | 免费福利在线观看 | 国产色在线观看 | 免费在线观看日韩欧美 | 国产视频精品久久 | 六月色婷婷 | 欧美日韩大片在线观看 | 国产精品久久久久久高潮 | 丁香婷婷激情国产高清秒播 | 亚洲成人精品av | 久久久这里有精品 | 成年人视频免费在线 | 国产黄色精品在线 | 91网站观看 | www.久久色| 日韩a在线观看 | 久久黄色影视 | 欧美成人一二区 | av先锋中文字幕 | 97超碰资源网 | 在线а√天堂中文官网 | 青青草视频精品 | 日韩精品一区在线观看 | 免费看一级特黄a大片 | 久久久久免费精品视频 | 久久综合久久综合这里只有精品 | 欧美午夜精品久久久久久浪潮 | 久久免费影院 | 免费在线观看日韩 | 五月婷婷综合网 | 日韩在线免费小视频 | 激情av网址 | av福利第一导航 | 亚洲精品啊啊啊 | 91视频 - v11av| 亚洲国产中文字幕在线视频综合 | 国产亚洲日本 | 久久久久亚洲精品成人网小说 | 99精品欧美一区二区三区黑人哦 | av在线看网站 | 国产成人333kkk | 999国产 | 国产一区二区中文字幕 | 99在线视频播放 | 黄色三级网站在线观看 | 国产女人40精品一区毛片视频 | 国内久久精品 | 欧美日韩免费观看一区=区三区 | 成人毛片在线观看 | 成人久久 | 国产精品99久久免费黑人 | 欧美日韩大片在线观看 | 精品久久国产 | 天天曰天天干 | 91精品999 | 97超碰色偷偷 | 五月综合在线观看 | 国产精品午夜免费福利视频 | 91中文字幕在线视频 | 韩国av电影网 | 国产一区在线看 | 日韩av专区| 精品国产一区二区三区久久久蜜臀 | 日韩美女高潮 | 亚洲欧洲成人精品av97 | 国产乱对白刺激视频不卡 | 亚洲精品ww| 国产淫片免费看 | 日韩在线一区二区免费 | 亚洲国产av精品毛片鲁大师 | 日日碰狠狠添天天爽超碰97久久 | 色综合久久综合中文综合网 | 激情五月视频 | 国产欧美精品一区二区三区四区 | av成人免费在线观看 | 婷婷精品国产一区二区三区日韩 | 亚洲免费视频在线观看 | 国产麻豆精品95视频 | 欧美精品一区二区性色 | 久草在线免费看视频 | 91精品国产乱码久久 | 免费看的黄色的网站 | 婷婷伊人五月 | 天天综合色网 | 最近中文字幕大全 | 成人超碰在线 | 狠狠色香婷婷久久亚洲精品 | 99re国产 | 日韩久久影院 | 日韩福利在线观看 | 日韩精品中文字幕有码 | 国产亚洲激情视频在线 | 午夜国产影院 | 美女黄频 | 波多野结衣一区三区 | 亚洲 欧美 国产 va在线影院 | 天堂av高清 | 久草视频视频在线播放 | 国产主播大尺度精品福利免费 | 一级α片免费看 | 99热在线网站 | 成年人免费看的视频 | 亚洲日本精品 | 偷拍福利视频一区二区三区 | 51久久成人国产精品麻豆 | 国产精品毛片久久 | 在线观看的av | 国产日产高清dvd碟片 | 1024手机基地在线观看 | 亚洲精品a区 | 久草久草久草久草 | 青青啪 | 亚洲在线免费视频 | 欧美成年网站 | 操久久免费视频 | 亚洲欧美国产精品久久久久 | 欧美精品久久99 | 深爱综合网 | 色免费在线 | 亚洲精品国产综合99久久夜夜嗨 | 国产午夜视频在线观看 | 西西www4444大胆在线 | 在线观看免费观看在线91 | 一级黄色在线免费观看 | 超碰97人人干 | 在线观看播放av | 啪啪激情网| 国产电影黄色av | 又湿又紧又大又爽a视频国产 | 成人性生交大片免费观看网站 | 狠狠狠狠狠狠狠 | 欧美男同网站 | 干狠狠| av中文在线 | 天天操天天操天天操天天操 | 国产日韩在线观看一区 | 久久a免费视频 | 成人免费视频a | 久久伦理| 久久综合久久综合久久 | 亚洲精品综合一区二区 | 在线看v片 | 在线亚洲人成电影网站色www | 高清av不卡 | 国产99一区视频免费 | 91成人在线观看喷潮 | 久久国产经典 | 精品视频99 | 成年人在线免费看视频 | 97手机电影网 | 国产国产人免费人成免费视频 | 久久y| 日韩精品一区电影 | 亚洲视屏 | 亚洲黄色在线观看 | 国内亚洲精品 | 久久精品一二三区白丝高潮 | 中文字幕免费观看全部电影 | 亚洲欧美日韩不卡 | 日日干 天天干 | 亚洲国产字幕 | 狠狠色伊人亚洲综合网站色 | 国产剧情一区在线 | 久久精品国产免费看久久精品 | 久久这里只有精品视频99 | 日韩精品在线视频免费观看 | 91丨九色丨91啦蝌蚪老版 | 国产午夜精品理论片在线 | 欧美aa一级片 | 伊人手机在线 | 中文字幕在线观看亚洲 | 欧美日韩aa | 亚洲视频观看 | 婷婷伊人综合亚洲综合网 | 51精品国自产在线 | 毛片无卡免费无播放器 | 麻豆久久久久久久 | 久久九九视频 | 久久经典国产 | 97超碰在线免费观看 | 天天拍天天草 | 免费a视频| 国产高清网站 | 韩国av免费观看 | 日韩欧美69| 激情五月av | 久草视频免费看 | 国产视频精品久久 | 97超碰在线免费观看 | 国产精品91一区 | 特级西西人体444是什么意思 | 婷婷午夜| 国产黄色免费 | 视频在线观看一区 | 日韩啪啪小视频 | 中文字幕在线日 | 在线最新av | 人人爽人人搞 | 国产福利av在线 | 日韩天天操 | 91视频a| 九九日韩 | 91九色porny在线| 成人高清av在线 | 天天综合网久久综合网 | 成年人在线视频观看 | 国产精品一区二区免费在线观看 | 97色涩| 国产在线观看二区 | 日韩美女免费线视频 | 在线观看日本韩国电影 | 91视频国产免费 | 久久久久久久免费 | 九九免费精品视频 | 精品极品在线 | 91在线看免费 | 久久久久免费视频 | 欧美一级裸体视频 | 国产区在线看 | 波多野结衣久久精品 | 亚洲国产精品视频 | 伊人久久电影网 | www.国产在线视频 | 久久国产免费视频 | 免费观看性生活大片 | 亚洲1级片| 国产九色在线播放九色 | 日韩欧美在线观看一区 | 成人国产亚洲 | 草久视频在线观看 | 色吊丝在线永久观看最新版本 | 欧美日韩亚洲在线 | 久久永久免费 | 天天色天天上天天操 | 2019中文在线观看 | 一区电影 | 日韩色在线观看 | 国产一区在线不卡 | 最新久久久 | 超碰人人草 | 一区二区精 | 在线观看aa| 日韩色视频在线观看 | 91看片在线| 国产精品原创av片国产免费 | 日韩国产精品久久久久久亚洲 | 日本精品在线 | 人成午夜视频 | 狠狠干干 | 久久dvd| 国产精品手机在线 | 欧美日韩后 | 久久精品一区二区三区视频 | 日韩在线高清免费视频 | 91精品视频导航 | 中文字幕在线观看一区二区 | 成人av影视 | 2018亚洲男人天堂 | 亚洲精品五月天 | 欧美精品乱码久久久久久按摩 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 黄色大全视频 | 日韩欧美国产成人 | 亚洲国产理论片 | 蜜桃av观看 | 国产国产人免费人成免费视频 | 超碰在线94 | 超碰av在线免费观看 | 久久久久 免费视频 | 久久久精品 一区二区三区 国产99视频在线观看 | 亚洲精品在线一区二区 | 一区二区 精品 | 狠狠色噜噜狠狠狠合久 | 久草免费手机视频 | 一区电影 | 最近中文字幕大全中文字幕免费 | 国产在线精品二区 | 激情欧美xxxx | 日韩最新在线视频 | 丁香六月综合网 | 久久久黄色av | 亚洲最大成人免费网站 | 久久久久久久久久免费视频 | 在线免费黄色毛片 | 夜夜澡人模人人添人人看 | 天天激情| 五月天婷婷视频 | 五月婷婷中文网 | 国产一级h | 在线视频 一区二区 | 国产91精品看黄网站在线观看动漫 | 黄色小说在线免费观看 | 免费视频 你懂的 | 久久精品国产一区二区三 | 精品亚洲成人 | 视频1区2区| 天天操天天干天天玩 | 天天看天天干 | 亚州精品天堂中文字幕 | 亚洲欧美视频在线 | 免费日韩三级 | 91网免费观看 | 欧美美女视频在线观看 | 日本护士三级少妇三级999 | 天天激情站 | 日韩视 | 久久社区视频 | 亚洲精品视频在线免费播放 | 久久精品国产一区二区三区 | 欧美性色xo影院 | 五月天电影免费在线观看一区 | 黄色免费网 | 婷婷网址 | 亚洲黄色大片 | 黄色精品久久久 | 国产不卡高清 | 在线免费观看国产 | 精品国偷自产国产一区 | 99精品在这里 | 国产精品区免费视频 | 国产美女视频免费观看的网站 | 热久久免费国产视频 | 最近日韩免费视频 | 日韩视频免费在线 | 中文字幕久久网 | 99精品视频在线免费观看 | 久久8精品 | 成人在线视频你懂的 | 中文字幕日本特黄aa毛片 | 免费观看一级特黄欧美大片 | 亚洲精品视频网址 | 久久视讯 | 一区 二区电影免费在线观看 | 中文综合在线 | 国产高清免费在线播放 | 中文字幕精品一区久久久久 | 激情久久久 | 国产黄色片免费看 | 国产黄a三级三级 | av成人在线看 | 久久免费精品一区二区三区 | 99色人 | 国产成人精品一区二区三区 | 黄色网www| 美女视频黄免费网站 | 国产.精品.日韩.另类.中文.在线.播放 | 中文av一区二区 | 午夜精品久久久久99热app | 欧美精品一区二区三区四区在线 | 在线观看视频97 | 亚洲精品久久久久中文字幕二区 | 91九色porn在线资源 | av色综合| 国产精品自拍在线 | 91你懂的 | 国产国语在线 | 亚洲视频在线观看网站 | 国产综合视频在线观看 | 丁香亚洲| 激情av在线播放 | 精品国产久 | 国产亚洲精品成人av久久影院 | 日本中文在线观看 | 高清久久久久久 | 五月天婷婷狠狠 | 在线观看黄色的网站 | 成人免费视频在线观看 | 69av视频在线观看 | 亚洲激情六月 | 又黄又刺激又爽的视频 | 91精品人成在线观看 | 成人一级在线 | 国产精品一区在线观看 | 色天天综合网 | 亚洲精品av中文字幕在线在线 | 国产成人精品一区二区三区在线观看 | 亚洲欧洲av| 超碰在线最新地址 | 亚洲成人精品久久 | 久久国产精品小视频 | 国产亚洲日 | 中文字幕电影网 | 久久精品永久免费 | 久久精品99国产精品酒店日本 | 麻豆高清免费国产一区 | 日韩字幕 |