打开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();
}
LocationManagerService的systemRunning方法中会监听setting数据库中的location_providers_allowed字段值的变化,
/frameworks/base/services/core/java/com/android/server/LocationManagerService.java
// listen for settings changes
mContext.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");
}
}
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;
};
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有