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来完成此功能。
(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
提供给客户端使用的定位服务相关类。
开机后由系统启动系统定位服务LocationManagerService。
1) 加载和启动提供定位服务的各个定位模块LocationProviderInterface;
2) 注册网络更新;
3) 注册包管理更新,监听设置变化信息,获取各个定位模块可用信息。
客户端应用实现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的位置监听记录。
当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);更新客户端应用所需要的位置信息。
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。
1)实现网络定位模块
LocationProvider为网络定位的基类,外部需要继承并实现它; LocationProvider中创建了一个接口类 ILocationProvider,用于与LBS系统服务交互。
2)启动网络定位模块
LocationProviderProxy启动网络定位服务模块,网络定位服务模块创建LocationProvider,
并与之建立连接; 网络定位服务启动成功后,会传给LocationProviderProxy 已经创建好的ILocationProvider对象。
LocationManagerService会调用ILocationProvider的接口函数,进而调用到LocationProvider的函数。
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。
1)实现地址编码模块
GeocodeProvider为地址编码模块的基类,外部需要继承并实现它;
GeocodeProvider中创建了一个接口类 IGeocodeProvider,用于与LBS系统服务交互。
2)启动地址编码模块
GeocoderProxy启动地址编码模块GeocodeProvider,
并与之建立连接; GeocodeProvider启动成功后,会通过getBinder() 传给GeocoderProxy已经创建好的IGeocodeProvider对象。
LocationManagerService中的GeocodeProxy会调用IGeocodeProvider的接口函数,进而调用到GeocodeProvider的函数。