Android Location switch process analysis
A colleague found that the current location of the car is flashing (after the wire flashing), and the initial value of the location (seen in the settings) is inconsistent each time. I have never touched this before, so I took it out for research today. Put together a blog.
Three working modes of location?
From the settings->location interface, location mainly has three working modes:
high_accuracy battery_saving sensors_only
Corresponding code:
//packages/apps/Settings/src/com/android/settings/location/LocationMode.java
int mode = Settings.Secure.LOCATION_MODE_OFF;//其实还有一种off模式
if (emiter == mHighAccuracy) {
mode = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
} else if (emiter == mBatterySaving) {
mode = Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
} else if (emiter == mSensorsOnly) {
mode = Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
}
setLocationMode(mode);
Quickly find setLocationMode
//packages/apps/Settings/src/com/android/settings/location/LocationSettingsBase.java
public void setLocationMode(int mode) {
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");
}
mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
Settings.Secure.LOCATION_MODE_OFF);
if (mActive) {
onModeChanged(mode, true);
}
return;
}
Intent intent = new Intent(MODE_CHANGING_ACTION);
intent.putExtra(CURRENT_MODE_KEY, mCurrentMode);
intent.putExtra(NEW_MODE_KEY, mode);
getActivity().sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode);
refreshLocationMode();
}
It seems to be operating the Settings.Secure database. Go find it directly:
private static final boolean setLocationModeForUser(ContentResolver cr, int mode,
int userId) {
...
switch (mode) {
case LOCATION_MODE_OFF:
break;
case LOCATION_MODE_SENSORS_ONLY:
gps = true;
break;
case LOCATION_MODE_BATTERY_SAVING:
network = true;
break;
case LOCATION_MODE_HIGH_ACCURACY:
gps = true;
network = true;
break;
default:
throw new IllegalArgumentException("Invalid location mode: " + mode);
}
// Note it's important that we set the NLP mode first. The Google implementation
// of NLP clears its NLP consent setting any time it receives a
// LocationManager.PROVIDERS_CHANGED_ACTION broadcast and NLP is disabled. Also,
// it shows an NLP consent dialog any time it receives the broadcast, NLP is
// enabled, and the NLP consent is not set. If 1) we were to enable GPS first,
// 2) a setup wizard has its own NLP consent UI that sets the NLP consent setting,
// and 3) the receiver happened to complete before we enabled NLP, then the Google
// NLP would detect the attempt to enable NLP and show a redundant NLP consent
// dialog. Then the people who wrote the setup wizard would be sad.
boolean nlpSuccess = Settings.Secure.setLocationProviderEnabledForUser(
cr, LocationManager.NETWORK_PROVIDER, network, userId);
boolean gpsSuccess = Settings.Secure.setLocationProviderEnabledForUser(
cr, LocationManager.GPS_PROVIDER, gps, userId);
return gpsSuccess && nlpSuccess;
}
public static final boolean setLocationProviderEnabledForUser(ContentResolver cr,
String provider, boolean enabled, int userId) {
synchronized (mLocationSettingsLock) {
// to ensure thread safety, we write the provider name with a '+' or '-'
// and let the SettingsProvider handle it rather than reading and modifying
// the list of enabled providers.
if (enabled) {
provider = "+" + provider;
} else {
provider = "-" + provider;
}
return putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
userId);
}
}
Yes, the field is what it is: Settings.Secure.LOCATION_PROVIDERS_ALLOWED
Look at the actual machine test:
old rules, one order to get it done
adb shell settings get secure location_providers_allowed
1. Close location:
The result is empty
2. Open location, high_accuracy mode
network,gps
3. Open location, battery_saving mode
network
4. Open location, sensors_only mode
gps
That's it. It can be regarded as popular science learning!