定位服务架构
如上图所示:
定位服务共分为四层:
最上面是应用层,以java为主。
第二层是框架层,这一层包含了供应用调用的接口及其系统服务的实现,主要由 Java 语言来实现。
第三层是硬件抽象层,本层由 C 以及 C++ 语言实现 , 框架层与共享库层使用 JNI 进行衔接。
最下面一层是 Linux 内核层 , 整个 Android 系统都是以 Linux 内核为基础的
FW-->HW之间的通信,对于android8.0以上的版本来说稍微复杂一下。android8.0以上的版本加入HIDL,JNI会通过HIDL来间接调和HW进行通信。
2.GPS初始化流程
1.在SystemServer.java中添加定位服务并通过systemrunning开启
try {
location = new LocationManagerService(context);
ServiceManager.addService(Context.LOCATION_SERVICE, location);
} catch (Throwable e) {
reportWtf("starting Location Manager", e);
}
----------------------------------------------
try {
if (locationF != null) locationF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying Location Service running", e);
}
2.LocationManagerService.systemRunning //prepare providers
// prepare providers
loadProvidersLocked();
updateProvidersLocked();
3.loadProvidersLocked //加载GnssLocationProvider
这里只针对GPS,所以只贴了GNSS的相关代码。其实加载的供应者还有passive,fuse,network相关的provider,请自行分析。
if (GnssLocationProvider.isSupported() && !WCN_DISABLED && HAS_GPS_FEATURE) {
// Create a gps location provider
GnssLocationProvider gnssProvider = new GnssLocationProvider(mContext, this,
mLocationHandler.getLooper());
mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider();
mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider();
mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider();
mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
addProviderLocked(gnssProvider);
mRealProviders.put(LocationManager.GPS_PROVIDER, gnssProvider);
mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider();
mGnssNavigationMessageProvider = gnssProvider.getGnssNavigationMessageProvider();
mGpsGeofenceProxy = gnssProvider.getGpsGeofenceProxy();
} else {
if (D) Log.d(TAG, "gnss location provider not support !");
}
4.加载之前首先要判断是否支持GNSS,其实在调用isSupproted之前,Gnss对providers做初始化工作,即图中的class_init_naitve。若是支持的话,isSupported肯定返回的是true,然后建立GnssLocationProvider对象,并加入链表记录下来。
5.updateProvidersLocked--》updateProviderListenersLocked
if (enabled) {
p.enable();
if (listeners > 0) {
applyRequirementsLocked(provider);
}
} else {
p.disable();
}
该步骤的功能会根据相应的provider的开启状态进行关闭或开启。例如,若Gnss未开启,则会执行p.enable()开启Gnss。
至于GPS定位功能的使用,其实更简单了,这里只做一些简单的说明。
1.获取Location服务
2.判断是否支持GPS定位
3.若支持,则requestLocationUpdates请求定位更新