Android 网络定位流程

        上一篇我们记录了 GPS 的定位流程,这一篇记录下 NLP(Network Location Provider)的定位流程,因为在国内,无法使用谷歌提供的NLP,所以国内我们一般会使用三方提供的NLP,比如:百度、高德、腾讯等。

        这里我们假设一个app发起 NLP 定位,首先调用 LocationManager 接口,通过AIDL最终调用到 LocationManagerService 里面的  requestLocationUpdates 方法:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/location/java/android/location/LocationManager.java#requestLocationUpdates

554    public void requestLocationUpdates(String provider, long minTime, float minDistance,
555            LocationListener listener) {
556        checkProvider(provider);
557        checkListener(listener);
558
559        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
560                provider, minTime, minDistance, false);
561        requestLocationUpdates(request, listener, null, null);
562    }

到这里我们就知道了,不管是GPS还是NLP,调用的都是这个接口,区别就是传进去的参数不一样,例如:provider,在Android 里面我们有以下几种provider:

Gps_provider、Network_provider、Passive_provider、Fused_provider、Mock_provider,其中前三种比较常用,Fused_provider依赖三方,比如谷歌GMS包。Mock_provider就是我们常说的伪造位置,一些虚拟定位软件就是基于这个开发的,这里我们暂时不记录,需要的后续单独详细讲。

继续看流程调用:

http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/LocationManagerService.java#requestLocationUpdates

2061    public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
2062            PendingIntent intent, String packageName) {
2063        if (request == null) request = DEFAULT_LOCATION_REQUEST;
2064        checkPackageName(packageName);
2065        int allowedResolutionLevel = getCallerAllowedResolutionLevel();
2066        checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
2067                request.getProvider());
2068        WorkSource workSource = request.getWorkSource();
2069        if (workSource != null && !workSource.isEmpty()) {
2070            checkDeviceStatsAllowed();
2071        }
2072        boolean hideFromAppOps = request.getHideFromAppOps();
2073        if (hideFromAppOps) {
2074            checkUpdateAppOpsAllowed();
2075        }
2076        boolean callerHasLocationHardwarePermission =
2077                mContext.checkCallingPermission(android.Manifest.permission.LOCATION_HARDWARE)
2078                        == PERMISSION_GRANTED;
2079        LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel,
2080                callerHasLocationHardwarePermission);
2081
2082        final int pid = Binder.getCallingPid();
2083        final int uid = Binder.getCallingUid();
2084        // providers may use public location API's, need to clear identity
2085        long identity = Binder.clearCallingIdentity();
2086        try {
2087            // We don't check for MODE_IGNORED here; we will do that when we go to deliver
2088            // a location.
2089            checkLocationAccess(pid, uid, packageName, allowedResolutionLevel);
2090
2091            synchronized (mLock) {
2092                Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
2093                        packageName, workSource, hideFromAppOps);
2094                requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName);
2095            }
2096        } finally {
2097            Binder.restoreCallingIdentity(identity);
2098        }
2099    }

这个流程其实都是一样的和GPS,最终到 applyRequirementsLocked 方法里这个地方,之前讲过:P指的是 LocationProviderInterface接口,而所有的provider要实现它,而这里我们请求的是网络 provider,此时网络的provider是三方实现的,就会走到具体实现的地方

1816        if (D) Log.d(TAG, "provider request: " + provider + " " + providerRequest);
1817        p.setRequest(providerRequest, worksource);

 而 LocationManagerService 在 systemRunning 的时候就去bind 三方的包,这样在请求Network_provider的时候就是走到绑定的三方接口里

636        // bind to network provider
637        LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind(
638                mContext,
639                LocationManager.NETWORK_PROVIDER,
640                NETWORK_LOCATION_SERVICE_ACTION,
641                com.android.internal.R.bool.config_enableNetworkLocationOverlay,
642                com.android.internal.R.string.config_networkLocationProviderPackageName,
643                com.android.internal.R.array.config_locationProviderPackageNames,
644                mLocationHandler);
645        if (networkProvider != null) {
646            mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider);
647            mProxyProviders.add(networkProvider);
648            addProviderLocked(networkProvider);
649        } else {
650            Slog.w(TAG, "no network location provider found");
651        }

 至此,大致流程梳理完毕。

文章同步来自微信公众号,更多内容关注公众号:蘑菇君先生

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值