Search code examples
androidandroid-settingsandroid-gps

Android: Can I enable the GPS without redirecting the user to the settings screen like in "google maps" app


In GPS based applications, it is important that the user enable his GPS. If not then usually we would show a dialog stating that the user "should enable his GPS from the settings to be able to use this functionality".

When the user press OK he will be redirected to the Settings page, I don't like this solution since it takes the user out of the application context in to the settings.

I have noticed that "google maps" application has a better solution, which is to show a neat dialog when a GPS feature is needed. Upon the user's selection "OK" GPS will be enabled directly without any redirection to the settings.

Can I enable the GPS without redirecting the user to the settings screen like in "google maps" app?

checkout the image below:

Neat Dialog


Solution

  • To have that feature you need:

    • First (at least) the version 7.0 of play services

    compile 'com.google.android.gms:play-services-location:16.0.0'

    • Second something like this in your code (I had it in my onCreate):

    -

     // Check the location settings of the user and create the callback to react to the different possibilities
    LocationSettingsRequest.Builder locationSettingsRequestBuilder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(mLocationRequest);
    PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, locationSettingsRequestBuilder.build());
    result.setResultCallback(mResultCallbackFromSettings);
    

    And then create the callback:

    // The callback for the management of the user settings regarding location
    private ResultCallback<LocationSettingsResult> mResultCallbackFromSettings = new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            //final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can initialize location
                    // requests here.
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the user
                    // a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                MapActivity.this,
                                REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    Log.e(TAG, "Settings change unavailable. We have no way to fix the settings so we won't show the dialog.");
                    break;
            }
        }
    };
    

    And then, finally, in onActivityResult I had the following:

    /**
     * Used to check the result of the check of the user location settings
     *
     * @param requestCode code of the request made
     * @param resultCode code of the result of that request
     * @param intent intent with further information
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        //final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent);
        switch (requestCode) {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        if (mGoogleApiClient.isConnected() && userMarker == null) {
                            startLocationUpdates();
                        }
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        break;
                    default:
                        break;
                }
                break;
        }
    }