Android GPS源碼分析總結

Android GPS源碼分析總結


本篇主要包括如下內容:
1. 術語介紹
2. 應用層開發總結
3. framework分析
4. HAL層接口介紹


1. 術語介紹
1.1 GNSS

GNSS爲Global Navigation Satellite System的縮寫,即全球導航衛星系統。當前應用較廣泛的主要有美國的GPS、俄羅斯的GLONASS、歐盟的GALILEO和中國北斗衛星導航系統等4大GNSS系統。


1.2 NMEA-0183
NMEA 0183是美國國家海洋電子協會(National Marine Electronics Association )爲海用電子設備制定的標準格式。目前業已成了GPS導航設備統一的RTCM(Radio Technical Commission for Maritime services)標準協議。

NMEA-0183協議採用ASCII碼,定義的語句非常多,但是常用的只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。舉個例子如下:

$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也將被傳輸,如果不是差分定位將爲空)


1.3 GIS
地理信息系統(GIS,Geographic Information System)是一門綜合性學科,結合地理學與地圖學以及遙感和計算機科學,已經廣泛的應用在不同的領域,是用於輸入、存儲、查詢、分析和顯示地理數據的計算機系統,隨着GIS的發展,也有稱GIS爲“地理信息科學”(Geographic Information Science),近年來,也有稱GIS爲"地理信息服務"(Geographic Information service)。

1.4 地理編碼
  地理編碼指將地名的詳細地址以地理座標(如經緯度)表示的過程。其中,將地址信息映射爲地理座標的過程稱之爲地理編碼;將地理座標轉換爲地址信息的過程稱之爲逆地理編碼。

2. 應用層開發
2.1 AndroidManifest.xml中權限添加
<uses-permission android:name="android.permission.INTERNET" />     
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />     
<uses-permission android:name="android.permission.ACCESS_FIND_LOCATION" />    
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> 
2.2 Interfaces

GpsStatus.Listener This interface was deprecated in API level 24. use GnssStatus.Callback instead. 
GpsStatus.NmeaListener This interface was deprecated in API level 24. use OnNmeaMessageListener instead. 
LocationListener Used for receiving notifications from the LocationManager when the location has changed. 
OnNmeaMessageListener Used for receiving NMEA sentences from the GNSS. 

2.3 Classes

Address A class representing an Address, i.e, a set of Strings describing a location. 
Criteria A class indicating the application criteria for selecting a location provider. 
Geocoder A class for handling geocoding and reverse geocoding. 
GnssClock A class containing a GPS clock timestamp. 
GnssMeasurement A class representing a GNSS satellite measurement, containing raw and computed information. 
GnssMeasurementsEvent A class implementing a container for data associated with a measurement event. 
GnssMeasurementsEvent.Callback Used for receiving GNSS satellite measurements from the GNSS engine. 
GnssNavigationMessage A class containing a GNSS satellite Navigation Message. 
GnssNavigationMessage.Callback Used for receiving GNSS satellite Navigation Messages from the GNSS engine. 
GnssStatus This class represents the current state of the GNSS engine. 
GnssStatus.Callback Used for receiving notifications when GNSS events happen. 
GpsSatellite This class was deprecated in API level 24. use GnssStatus and GnssStatus.Callback. 
GpsStatus This class was deprecated in API level 24. use GnssStatus and GnssStatus.Callback. 
Location A data class representing a geographic location. 
LocationManager This class provides access to the system location services. 
LocationProvider An abstract superclass for location providers. 
SettingInjectorService Dynamically specifies the summary (subtitle) and enabled status of a preference injected into the list of app settings displayed by the system settings app

For use only by apps that are included in the system image, for preferences that affect multiple apps. 

2.4 sample code
進行GPS應用開發牽涉到的接口或類位於android.location這個package,使用流程大體如下。

3. framework分析
3.1 類圖

說明如下:
1.GPS Framework邏輯設計上可分爲GPS Client和GPS Server兩部分,兩者之間基於接口進行通信(Binder機制):ILocationListner、IGpsStatusListner、ILocationManager等。開發上的依賴關係爲:APK -> GPS Client -> GPS Server -> GPS HAL Layer;
2.ILocationManager的Bn端實現爲LocationManagerService,供GPS Client端調用;
3.這裏的GPS Client並不是絕對的充當Client(客戶端)角色,其中的LocationListner、IGpsStatusListner的接口實現類(Bn端)充當Server(服務端)角色,供HAL層間接調用以通知GPS狀態信息;
4.藍色標註的部分爲HAL層接口,後面會介紹。
5.GPS Client端的關鍵類設計意圖上面已有介紹,這裏摘錄GPS Server端幾個關鍵類的設計意圖如下:

/**
 * System private API for talking with the location service.
 *
 * @hide
 */
interface ILocationManager{
......
}



/**
* The service class that manages LocationProviders and issues location
* updates and alerts.
*/
public class LocationManagerService extends ILocationManager.Stub {
......
}

/**
* Location Manager's interface for location providers.
* @hide
*/
public interface LocationProviderInterface {
public String getName();

public void enable();
public void disable();
public boolean isEnabled();
public void setRequest(ProviderRequest request, WorkSource source);

public void dump(FileDescriptor fd, PrintWriter pw, String[] args);

// --- deprecated (but still supported) ---
public ProviderProperties getProperties();
public int getStatus(Bundle extras);
public long getStatusUpdateTime();
public boolean sendExtraCommand(String command, Bundle extras);
}

/**
* A GPS implementation of LocationProvider used by LocationManager.
*
* {@hide}
*/
public class GpsLocationProvider implements LocationProviderInterface {
......
}

3.2 序列圖
3.2.1 GPS Client端初始化

上圖主要完成開機後LocationManger的實例創建,App開發人員可以透過context.getSystemService()獲取到此實例。

3.2.2 GPS Server端初始化

上圖主要完成了LocationManagerService的創建、註冊以及GPS Module(HAL Layer)的初始化動作,細節請參考源碼。

4. HAL層接口介紹

/** 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;


/** GPS callback structure. */
typedef struct {
/** set to sizeof(GpsCallbacks) */
size_t size;
//位置信息
gps_location_callback location_cb;
//GPS狀態信息
gps_status_callback status_cb; 
//衛星信息
gps_sv_status_callback sv_status_cb;
//NMEA log信息
gps_nmea_callback nmea_cb;
//GPS支持度
gps_set_capabilities set_capabilities_cb;
//This can be used to prevent the CPU from suspending while handling GPS events.
gps_acquire_wakelock acquire_wakelock_cb;
//Callback utility for releasing the GPS wakelock.
gps_release_wakelock release_wakelock_cb;
//Callback for creating a thread that can call into the Java framework code.
gps_create_thread create_thread_cb;
//Callback for requesting NTP time
gps_request_utc_time request_utc_time_cb;
} GpsCallbacks;

/** GPS status event values. */
//GPS狀態定義
typedef uint16_t GpsStatusValue;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
/** GPS status unknown. */
#define GPS_STATUS_NONE 0
/** GPS has begun navigating. */
#define GPS_STATUS_SESSION_BEGIN 1
/** GPS has stopped navigating. */
#define GPS_STATUS_SESSION_END 2
/** GPS has powered on but is not navigating. */
#define GPS_STATUS_ENGINE_ON 3
/** GPS is powered off. */
#define GPS_STATUS_ENGINE_OFF 4

/** Represents the status. */
//狀態信息
typedef struct {
/** set to sizeof(GpsStatus) */
size_t size;
GpsStatusValue status;
} GpsStatus;

/** Represents SV information. */
//衛星信息
typedef struct {
/** set to sizeof(GpsSvInfo) */
size_t size;
/** Pseudo-random number for the SV. */
int prn;//衛星編號
/** Signal to noise ratio. */
float snr;//信號強度
/** Elevation of SV in degrees. */
float elevation;//仰望角
/** Azimuth of SV in degrees. */
float azimuth;//方位角
} GpsSvInfo;

/** Represents the standard GPS interface. */
typedef struct {
/**
* Opens the interface and provides the callback routines
* to the implementation of this interface.
*/
// 註冊callback
int (*init)( GpsCallbacks* callbacks );

/** Starts navigating. */
// 啓動定位
int (*start)( void );

/** Stops navigating. */
// 取消定位
int (*stop)( void );

/** Closes the interface. */
// 關閉GPS
void (*cleanup)( void );
......
} GpsInterface;

參考:
1,https://developer.android.google.cn/reference/android/location/package-summary.html
2,https://baike.baidu.com/item/NMEA-0183/1810482?fr=aladdin
3,http://www.cnblogs.com/ljf181275034/articles/3238087.html
3,android 6.0源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章