Analysis of Android Location switching process

Analysis of Android Location switching process

A colleague found that the current location of the car engine is different from that of the brush (after the wire brush), and the initial value of each location (as seen in the settings) is different. I haven't touched this before, so I'll take it out for research today and gather a blog

Three working modes of location?

From the Settings > location interface, there are three main working modes of location:

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;//In fact, there is also an off mode
        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 to 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 it: settings. Secure. Location? Providers? Allowed

Take a look at the actual machine test:

Old rules, one order

adb shell settings get secure location_providers_allowed

1. Close location:

Result empty

2. On location, high-speed mode

network,gps

3. Open location and battery saving mode

network

4. Open location, sensors only mode

gps

That's it. It's also popular science learning!

Tags: network Android Java Google

Posted on Sun, 03 May 2020 11:15:12 -0400 by the apprentice webmaster