位置信息如何回调

这里以Gps返回位置为例:

/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp

// 可以看到对应的关系:
1141 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V");

// 位置上报,底层会回调  gnssLocationCb:

429Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
430    JNIEnv* env = getJniEnv();
431
432    jobject jLocation = translateLocation(env, location);
433    bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
434            GnssLocationFlags::HAS_LAT_LONG) != 0;
435
436    env->CallVoidMethod(mCallbacksObj,
437                        method_reportLocation,        ---> 对应java 侧 reportLocation 方法
438                        boolToJbool(hasLatLong),
439                        jLocation);
440    checkAndClearExceptionFromCallback(env, __FUNCTION__);
441    env->DeleteLocalRef(jLocation);
442    return Void();
443}

 http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java#reportLocation

1585    private void reportLocation(boolean hasLatLong, Location location) {
1586        sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1587    }

消息处理,然后调用 handleReportLocation方法:

1589    private void handleReportLocation(boolean hasLatLong, Location location) {
1590        if (location.hasSpeed()) {
1591            mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
1592        }
1593
1594        if (mItarSpeedLimitExceeded) {
1595            Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1596                    "  GPS/GNSS Navigation output blocked.");
1597            if (mStarted) {
1598                mGnssMetrics.logReceivedLocationStatus(false);
1599            }
1600            return;  // No output of location allowed
1601        }
1602
1603        if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
1604
1605        // It would be nice to push the elapsed real-time timestamp
1606        // further down the stack, but this is still useful
1607        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1608        location.setExtras(mLocationExtras.getBundle());
1609
1610        try {
1611            mILocationManager.reportLocation(location, false);   ---> 在LMS new GnssLocationProvider传下来,看下面两张图
1612        } catch (RemoteException e) {
1613            Log.e(TAG, "RemoteException calling reportLocation");
1614        }

 

 那就是调用到 LMS(LocationManagerService)

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

2835    public void reportLocation(Location location, boolean passive) {
2836        checkCallerIsProvider();
2837
2838        if (!location.isComplete()) {
2839            Log.w(TAG, "Dropping incomplete location: " + location);
2840            return;
2841        }
2842
2843        mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location);   
2844        Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location);  ---> 发给handlemessage处理
2845        m.arg1 = (passive ? 1 : 0);
2846        mLocationHandler.sendMessageAtFrontOfQueue(m);
2847    }
3081    private void handleLocationChanged(Location location, boolean passive) {
3082        // create a working copy of the incoming Location so that the service can modify it without
3083        // disturbing the caller's copy
3084        Location myLocation = new Location(location);
3085        String provider = myLocation.getProvider();
3086
3087        // set "isFromMockProvider" bit if location came from a mock provider. we do not clear this
3088        // bit if location did not come from a mock provider because passive/fused providers can
3089        // forward locations from mock providers, and should not grant them legitimacy in doing so.
3090        if (!myLocation.isFromMockProvider() && isMockProvider(provider)) {
3091            myLocation.setIsFromMockProvider(true);
3092        }
3093
3094        synchronized (mLock) {
3095            if (isAllowedByCurrentUserSettingsLocked(provider)) {
3096                if (!passive) {
3097                    // notify passive provider of the new location
3098                    mPassiveProvider.updateLocation(myLocation);
3099                }
3100                handleLocationChangedLocked(myLocation, passive);
3101            }
3102        }
3103    }
2882    private void handleLocationChangedLocked(Location location, boolean passive) {
2883        if (D) Log.d(TAG, "incoming location: " + location);
2884        long now = SystemClock.elapsedRealtime();
2885        String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider());
2886        // Skip if the provider is unknown.
2887        LocationProviderInterface p = mProvidersByName.get(provider);
2888        if (p == null) return;
2889        updateLastLocationLocked(location, provider);
2890        // mLastLocation should have been updated from the updateLastLocationLocked call above.
2891        Location lastLocation = mLastLocation.get(provider);
2892        if (lastLocation == null) {
2893            Log.e(TAG, "handleLocationChangedLocked() updateLastLocation failed");
2894            return;
2895        }
2896
2897        // Update last known coarse interval location if enough time has passed.
2898        Location lastLocationCoarseInterval = mLastLocationCoarseInterval.get(provider);
2899        if (lastLocationCoarseInterval == null) {
2900            lastLocationCoarseInterval = new Location(location);
2901            mLastLocationCoarseInterval.put(provider, lastLocationCoarseInterval);
2902        }
2903        long timeDiffNanos = location.getElapsedRealtimeNanos()
2904                - lastLocationCoarseInterval.getElapsedRealtimeNanos();
2905        if (timeDiffNanos > LocationFudger.FASTEST_INTERVAL_MS * NANOS_PER_MILLI) {
2906            lastLocationCoarseInterval.set(location);
2907        }
2908        // Don't ever return a coarse location that is more recent than the allowed update
2909        // interval (i.e. don't allow an app to keep registering and unregistering for
2910        // location updates to overcome the minimum interval).
2911        Location noGPSLocation =
2912                lastLocationCoarseInterval.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
2913
2914        // Skip if there are no UpdateRecords for this provider.
2915        ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
2916        if (records == null || records.size() == 0) return;
2917
2918        // Fetch coarse location
2919        Location coarseLocation = null;
2920        if (noGPSLocation != null) {
2921            coarseLocation = mLocationFudger.getOrCreate(noGPSLocation);
2922        }
2923
2924        // Fetch latest status update time
2925        long newStatusUpdateTime = p.getStatusUpdateTime();
2926
2927        // Get latest status
2928        Bundle extras = new Bundle();
2929        int status = p.getStatus(extras);
2930
2931        ArrayList<Receiver> deadReceivers = null;
2932        ArrayList<UpdateRecord> deadUpdateRecords = null;
2933
2934        // Broadcast location or status to all listeners
2935        for (UpdateRecord r : records) {
2936            Receiver receiver = r.mReceiver;
2937            boolean receiverDead = false;
2938
2939            int receiverUserId = UserHandle.getUserId(receiver.mIdentity.mUid);
2940            if (!isCurrentProfile(receiverUserId)
2941                    && !isUidALocationProvider(receiver.mIdentity.mUid)) {
2942                if (D) {
2943                    Log.d(TAG, "skipping loc update for background user " + receiverUserId +
2944                            " (current user: " + mCurrentUserId + ", app: " +
2945                            receiver.mIdentity.mPackageName + ")");
2946                }
2947                continue;
2948            }
2949
2950            if (mBlacklist.isBlacklisted(receiver.mIdentity.mPackageName)) {
2951                if (D) {
2952                    Log.d(TAG, "skipping loc update for blacklisted app: " +
2953                            receiver.mIdentity.mPackageName);
2954                }
2955                continue;
2956            }
2957
2958            if (!reportLocationAccessNoThrow(
2959                    receiver.mIdentity.mPid,
2960                    receiver.mIdentity.mUid,
2961                    receiver.mIdentity.mPackageName,
2962                    receiver.mAllowedResolutionLevel)) {
2963                if (D) {
2964                    Log.d(TAG, "skipping loc update for no op app: " +
2965                            receiver.mIdentity.mPackageName);
2966                }
2967                continue;
2968            }
2969            //coarse location 和 fine location 是有区别的,加了一个偏移量的逻辑
2970            Location notifyLocation;
2971            if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
2972                notifyLocation = coarseLocation;  // use coarse location
2973            } else {
2974                notifyLocation = lastLocation;  // use fine location
2975            }
2976            if (notifyLocation != null) {
2977                Location lastLoc = r.mLastFixBroadcast;
2978                if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) {  ---> 判断是否需要回调
2979                    if (lastLoc == null) {
2980                        lastLoc = new Location(notifyLocation);
2981                        r.mLastFixBroadcast = lastLoc;
2982                    } else {
2983                        lastLoc.set(notifyLocation);
2984                    }
2985                    if (!receiver.callLocationChangedLocked(notifyLocation)) {  ---> 开始回调注册的listen
2986                        Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver);
2987                        receiverDead = true;
2988                    }
2989                    r.mRealRequest.decrementNumUpdates();
2990                }
2991            }
977        public boolean callLocationChangedLocked(Location location) {
978            if (mListener != null) {
979                try {
980                    synchronized (this) {
981                        // synchronize to ensure incrementPendingBroadcastsLocked()
982                        // is called before decrementPendingBroadcasts()
983                        mListener.onLocationChanged(new Location(location));   ---> 回调给所注册的listener
984                        // call this after broadcasting so we do not increment
985                        // if we throw an exeption.
986                        incrementPendingBroadcastsLocked();
987                    }
988                } catch (RemoteException e) {
989                    return false;
990                }
991            } else { --->开始注册的是pending 走这里
992                Intent locationChanged = new Intent();
993                locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED,
994                        new Location(location));
995                try {
996                    synchronized (this) {
997                        // synchronize to ensure incrementPendingBroadcastsLocked()
998                        // is called before decrementPendingBroadcasts()
999                        mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler,
1000                                getResolutionPermission(mAllowedResolutionLevel),
1001                                PendingIntentUtils.createDontSendToRestrictedAppsBundle(null));
1002                        // call this after broadcasting so we do not increment
1003                        // if we throw an exeption.
1004                        incrementPendingBroadcastsLocked();
1005                    }
1006                } catch (PendingIntent.CanceledException e) {
1007                    return false;
1008                }
1009            }
1010            return true;
1011        }

至此,整个流程大致梳理完毕,最好抓份log,对着log梳理,如需要log可以公众号后台留言:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值