一、Settings

打开GPS的方法往数据库里面写值,然后framework层读取值再做相应处理。

packages/apps/Settings/src/com/android/settings/location/LocationSwitchBarController.java

public void onSwitchChanged(Switch switchView, boolean isChecked) {    mLocationEnabler.setLocationEnabled(isChecked);}

/packages/apps/Settings/src/com/android/settings/location/LocationEnabler.java

void setLocationMode(int mode) {    final int currentMode = Settings.Secure.getInt(mContext.getContentResolver(),            Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);    if (isRestricted()) {        // Location toggling disabled by user restriction. Read the current location mode to        // update the location master switch.        if (Log.isLoggable(TAG, Log.INFO)) {            Log.i(TAG, "Restricted user, not setting location mode");        }        if (mListener != null) {            mListener.onLocationModeChanged(currentMode, true);        }        return;    }    updateLocationMode(mContext, currentMode, mode, ActivityManager.getCurrentUser(),            Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);    refreshLocationMode();}

二、framework

LocationManagerService的systemRunning方法中会监听setting数据库中的location_providers_allowed字段值的变化,

/frameworks/base/services/core/java/com/android/server/LocationManagerService.java

// listen for settings changesmContext.getContentResolver().registerContentObserver(        Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,        new ContentObserver(mLocationHandler) {            @Override            public void onChange(boolean selfChange) {                synchronized (mLock) {                    updateProvidersLocked();                }            }        }, UserHandle.USER_ALL);

如果该值有变化,则调用updateProvidersLocked方法。

private void updateProvidersLocked() {    boolean changesMade = false;    for (int i = mProviders.size() - 1; i >= 0; i--) {        LocationProviderInterface p = mProviders.get(i);        boolean isEnabled = p.isEnabled();        String name = p.getName();        boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name);        if (isEnabled && !shouldBeEnabled) {            updateProviderListenersLocked(name, false);            mLastLocation.clear();            mLastLocationCoarseInterval.clear();            changesMade = true;        } else if (!isEnabled && shouldBeEnabled) {            updateProviderListenersLocked(name, true);            changesMade = true;        }    }    if (changesMade) {        mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),                UserHandle.ALL);        mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION),                UserHandle.ALL);    }}

在updateProvidersLocked方法中,如果支持gps,调用updateProviderListenersLocked方法。

private void updateProviderListenersLocked(String provider, boolean enabled) {    int listeners = 0;    LocationProviderInterface p = mProvidersByName.get(provider);    if (p == null) return;    ArrayList<Receiver> deadReceivers = null;    ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);    if (records != null) {        for (UpdateRecord record : records) {            if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {                // Sends a notification message to the receiver                if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {                    if (deadReceivers == null) {                        deadReceivers = new ArrayList<>();                    }                    deadReceivers.add(record.mReceiver);                }                listeners++;            }        }    }    if (deadReceivers != null) {        for (int i = deadReceivers.size() - 1; i >= 0; i--) {            removeUpdatesLocked(deadReceivers.get(i));        }    }    if (enabled) {        p.enable();        if (listeners > 0) {            applyRequirementsLocked(provider);        }    } else {        p.disable();    }}

GnssLocationProvider的enable方法如下:

/frameworks/base/services/core/java/com/android/server/location/GnssLocationProvider.java

GnssLocationProvider的enable方法如下:

public void enable() {    synchronized (mLock) {        if (mEnabled) return;        mEnabled = true;    }    sendMessage(ENABLE, 1, null);}

handlenable就是ENABLE的消息处理函数:

private void handleEnable() {    if (DEBUG) Log.d(TAG, "handleEnable");    boolean enabled = native_init();    if (enabled) {        mSupportsXtra = native_supports_xtra();        // TODO: remove the following native calls if we can make sure they are redundant.        if (mSuplServerHost != null) {            native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);        }        if (mC2KServerHost != null) {            native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);        }        mGnssMeasurementsProvider.onGpsEnabledChanged();        mGnssNavigationMessageProvider.onGpsEnabledChanged();        mGnssBatchingProvider.enable();    } else {        synchronized (mLock) {            mEnabled = false;        }        Log.w(TAG, "Failed to enable location provider");    }}

三、HAL

native_init对应jni中的android_location_GpsLocationProvider_init函数,在该函数中调用了
sGpsInterface->init(&sGpsCallbacks),

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

{"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {    /*     * This must be set before calling into the HAL library.     */    if (!mCallbacksObj)        mCallbacksObj = env->NewGlobalRef(obj);    /*     * Fail if the main interface fails to initialize     */    if (gnssHal == nullptr) {        ALOGE("Unable to Initialize GNSS HAL\n");        return JNI_FALSE;    }    sp<IGnssCallback> gnssCbIface = new GnssCallback();    Return<bool> result = false;    if (gnssHal_V1_1 != nullptr) {        result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);    } else {        result = gnssHal->setCallback(gnssCbIface);    }    if (!result.isOk() || !result) {        ALOGE("SetCallback for Gnss Interface fails\n");        return JNI_FALSE;    }    sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();    if (gnssXtraIface == nullptr) {        ALOGE("Unable to initialize GNSS Xtra interface\n");    } else {        result = gnssXtraIface->setCallback(gnssXtraCbIface);        if (!result.isOk() || !result) {            gnssXtraIface = nullptr;            ALOGI("SetCallback for Gnss Xtra Interface fails\n");        }    }    sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();    if (agnssIface != nullptr) {        agnssIface->setCallback(aGnssCbIface);    } else {        ALOGI("Unable to Initialize AGnss interface\n");    }    sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();    if (gnssGeofencingIface != nullptr) {      gnssGeofencingIface->setCallback(gnssGeofencingCbIface);    } else {        ALOGI("Unable to initialize GNSS Geofencing interface\n");    }    sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();    if (gnssNiIface != nullptr) {        gnssNiIface->setCallback(gnssNiCbIface);    } else {        ALOGI("Unable to initialize GNSS NI interface\n");    }    sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();    if (agnssRilIface != nullptr) {        agnssRilIface->setCallback(aGnssRilCbIface);    } else {        ALOGI("Unable to Initialize AGnss Ril interface\n");    }    return JNI_TRUE;}

这是将jni的一些函数作为参数传递到native c 空间中去,这样在native c中如果有可用数据将通过回调的方式调用到jni中的函数。简单的看一下 location_callback的定义:

struct GnssCallback : public IGnssCallback {    Return<void> gnssLocationCb(const GnssLocation& location) override;    Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;    Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;    Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;    Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;    Return<void> gnssAcquireWakelockCb() override;    Return<void> gnssReleaseWakelockCb() override;    Return<void> gnssRequestTimeCb() override;    Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;    Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;    // New in 1.1    Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;    // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics    static const char* sNmeaString;    static size_t sNmeaStringLength;};

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. 箭头函数的基础使用
  3. Python技巧匿名函数、回调函数和高阶函数
  4. Python list sort方法的具体使用
  5. python list.sort()根据多个关键字排序的方法实现
  6. Android(安卓)获取网络状态及调用网络配置界面(转帖)
  7. Android上调用google map api v2
  8. Android(安卓)UI系列:关于按钮点击事件
  9. Android文件浏览器的开发

随机推荐

  1. Android调试工具Genymotion的使用
  2. 【Android(安卓)Developers Training】 8
  3. MyEclip1se8.5搭建Android环境
  4. 从Android到IOS,IOS应用生命周期函数
  5. Android(安卓)4.0 SDK 环境搭建体验(Windo
  6. ViewPage滑动加载大图和点击关注效果《IT
  7. Robotium-无源码测试
  8. Android(安卓)SDK目录解析以及通用文件
  9. android学习--Android五大布局对象---Fra
  10. Ubuntu 14.04.3上配置并成功编译Android(