lbs系統由哪五部分組成?
1. LBS系統架構
LBS系統分為三大部分:
1) 第一部分為LBS客戶端管理部分,主要提供給客戶端應用使用,客戶端應用調用此部分提供的功能進行位置定位。
LocationManager,提供給客戶端應用調用,獲取位置等信息,同時當有位置信息變化時通知客戶端應用。
LocationListener,提供給客戶端應用注冊使用,每個客戶端應用對應一個LocationListener,通過LocationManager注冊到系統維護的一個位置服務的鏈表中,當系統中發現有位置信息變化或者其它信息變化時,會通過它通知客戶端應用。
GpsStatus,提供給客戶端應用獲取GPS定位服務的狀態。
GeoCoder,提供給客戶端應用調用,獲取地理編碼信息。
2)第二部分為LBS系統服務部分,開機時啟動此服務LocationManagerService,一方面負責處理LBS客戶端管理提供的定位等功能需求,另一方面啟動提供定位功能的功能模塊。
3)第三部分為LBS的定位功能服務部分,完成定位服務模塊的定位等動能。
GpsLocationProvider,提供GPS定位服務,通過GPS底層模塊獲取位置信息及狀態變化,通知LBS系統服務來獲取位置信息及狀態變化等。
LocationProviderProxy,提供網路定位服務,會通過ILocationProvider調用LocationProvider提供的定位功能。LocationProvider只是提供了一個抽象的定位服務模塊,并沒有真正實現定位功能,需要用戶去實現繼承LocationProvider來完成此功能。
GeocodeProxy,提供地址編碼服務,會通過IGeocodeProvider調用GeocodeProvider提供的正反向地址編碼功能。GeocodeProvider只提供了一個抽象的反向地址編碼服務模塊,根據經緯度來獲取地址信息,它并沒有真正實現反向地址編碼功能,需要用戶去實現繼承GeocodeProvider來完成此功能。
2. LBS目錄結構
(1) frameworks/base/services/java/com.android.server/LocationManager.java
提供的系統定位服務類。
(2) frameworks/base/services/java/com.android.server.location/
提供給系統定位服務使用的相關類。
(3) frameworks/base/location/lib/java/com.android.location.provider/
提供的抽象定位服務模塊類以及地址編碼服務模塊類。供用戶繼續以實現某種定位功能。
(4) frameworks/base/location/java/android.location
提供給客戶端使用的定位服務相關類。
3. LBS定位服務流程
3.1. 啟動系統定位服務
開機后由系統啟動系統定位服務LocationManagerService。
1) 加載和啟動提供定位服務的各個定位模塊LocationProviderInterface;
2) 注冊網絡更新;
3) 注冊包管理更新,監聽設置變化信息,獲取各個定位模塊可用信息。
3.2. 客戶端應用注冊監聽
客戶端應用實現LocationListener接口,通過LocationManager傳遞給LocationManagerService一個注冊監聽器,當定位模塊有狀態變化或者位置變化等信息變化時,定位模塊會通知LocationManagerService,LocationManagerService再通過該監聽器把信息變化發給對應的客戶端應用,然后客戶端應用再進行相應的處理。
1)客戶端應用調用LocationManager.requestLocationUpdates(Stringprovider,..., ILocationListener listener);
客戶端會實現一個接口LocationListener,封裝在ILocationListener中,通過參數傳入上面的函數中,進行注冊回調。
2)LocationManagerService.getReiver(ILocationListenerlistener);根據ILocationListener生成Receiver,并加入到LocationManagerService維護的一個HashMap<ILocationListener,Receiver>列表中。 當LocationManagerService發現有位置、狀態等信息變化時,調用該列表中的各個Receiver,通知客戶端應用對應的監聽器。
3)LocationManagerService.requestLocationLocked(Stringprovider,…,Receiver receiver);創建一個UpdateRecord(provider,…,receiver,uid),記錄客戶端監聽的記錄,存入到LocationManagerService維護的HashMap<String provider, ArrayList<UpdateRecord>>中,記錄客戶端對每個定位功能模塊provider的位置監聽記錄。
3.3. 系統定位服務通知狀態或者位置變化
當LocationMangerService收到定位功能模塊傳來的狀態或位置等信息變化時,會更新保存的狀態或者位置信息,同時通知客戶端監聽器列表中的各個客戶端監聽器。
以位置變化為例:
1)當定位模塊獲取到位置信息變化時,調用LocationManagerService.reportLocaiton(Localtion);
2) LocationManagerService通知其它的定位模塊LocationProviderInterface去更新位置信息,LocationProviderInterface.updateLocation(Location);
3)取出客戶端監聽器列表中的各個監聽器Receiver,更新位置信息,調用
Receiver.callLocationChangedLocked (Locatlion);
調用客戶端提供的回調函數接口:
ILocationListener.onLocationChanged (Location);
4) 客戶端應用更新位置信息:
LocationManager.ListenerTransport.onLocationChanged(Location);
調用LocationListener.onLocationChanged(Location);更新客戶端應用所需要的位置信息。
4. LBS網絡定位
4.1. LBS系統定位服務初始化網絡定位服務
1)獲取網絡定位模塊的包名
在LocationManagerService(…) 中
mNetworkLocationProviderPackageName =resources.getString(
com.android.internal.R.string.config_networkLocationProvider);
2)創建和啟動網絡定位模塊
在LocationManagerService._loadProvidersLocked()中,
如果網絡定位模塊的包名不為空,則:
創建一個LocationProviderProxy(LocationManager.NETWORK_PROVIDER,
mNetworkLocationProviderPackageName, …);
調用addProvider(…),將其加入到LocationManagerService維護的定位模塊列表中,以提供具體的定位服務。
3)LocationProviderProxy在創建時,通過調用bindService(…, ServiceConnection, Context.BIND_AUTO_CREATE),啟動綁定mNetworkLocationProviderPackageName對應的網絡定位服務,與此服務創建一個連接,創建成功后,會執行:
LocationProviderProxy.ServiceConnection.onServiceConnected(ComponentName className,IBinder service),獲取網絡定位服務模塊傳過來的調用接口ILocationProvider。
4.2. 網絡定位服務的實現和啟動
1)實現網絡定位模塊
LocationProvider為網絡定位的基類,外部需要繼承并實現它; LocationProvider中創建了一個接口類 ILocationProvider,用于與LBS系統服務交互。
2)啟動網絡定位模塊
LocationProviderProxy啟動網絡定位服務模塊,網絡定位服務模塊創建LocationProvider,
并與之建立連接; 網絡定位服務啟動成功后,會傳給LocationProviderProxy 已經創建好的ILocationProvider對象。
4.3. 系統定位服務調用網絡定位模塊
LocationManagerService會調用ILocationProvider的接口函數,進而調用到LocationProvider的函數。
5. LBS地址編碼
5.1. 系統定位服務中初始化
1)獲取地址編碼模塊的包名
在LocationManagerService(…) 中
mGeocodeProviderPackageName= resources.getString(
com.android.internal.R.string.config_geocodeProvider);
2)創建和啟動地址編碼模塊
在LocationManagerService._loadProvidersLocked()中,
如果地址編碼模塊的包名不為空,則:
創建一個GeocoderProxy(mGeocodeProviderPackageName)。
3)GeocoderProxy在創建時,通過調用bindService(…, ServiceConnection, Context.BIND_AUTO_CREATE), 啟動mGeocodeProviderPackageName對應的地址編碼服務,與此服務創建一個連接,創建成功后,會執行:
GeocoderProxy.ServiceConnection.onServiceConnected(ComponentNameclassName, IBinder service),獲取地址編碼模塊傳過來的調用接口IGeocodeProvider。
5.2. 地址編碼模塊的實現和啟動
1)實現地址編碼模塊
GeocodeProvider為地址編碼模塊的基類,外部需要繼承并實現它;
GeocodeProvider中創建了一個接口類 IGeocodeProvider,用于與LBS系統服務交互。
2)啟動地址編碼模塊
GeocoderProxy啟動地址編碼模塊GeocodeProvider,
并與之建立連接; GeocodeProvider啟動成功后,會通過getBinder() 傳給GeocoderProxy已經創建好的IGeocodeProvider對象。
5.3. 系統定位服務調用地址編碼模塊
LocationManagerService中的GeocodeProxy會調用IGeocodeProvider的接口函數,進而調用到GeocodeProvider的函數。