How to show enable location dialog like Google maps?
Asked Answered
S

13

138

I use the latest version of Google Play Services (7.0) and followed the steps given in their guide and I enabled the location dialog like below, which has a "never" button. My app needs location mandatorily so I don't want to show "never" to user, because once the user clicks "never", I'm unable to get location or request for location again at all.

Where as Google Maps has only yes and no button without never button, any idea how to achieve the same?

My app's image enter image description here

Google Map's image enter image description here

Sporocyte answered 22/4, 2015 at 14:52 Comment(1)
Here is my solution for kotlin users: #31236064Cynthiacynthie
O
151

LocationSettingsRequest.Builder has a method setAlwaysShow(boolean show). While the document indicates it's currently doing nothing(updated 2015-07-05: updated Google documentation has removed this wording), setting builder.setAlwaysShow(true); will enable Google Maps behavior: enter image description here

Here's the code that got it working:

if (googleApiClient == null) {
    googleApiClient = new GoogleApiClient.Builder(getActivity())
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    googleApiClient.connect();

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);

    //**************************
    builder.setAlwaysShow(true); //this is the key ingredient
    //**************************

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates state = 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(
                                getActivity(), 1000);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.
                    break;
            }
        }
    });
}

From Android Documentation

For Kotlin see here: https://mcmap.net/q/166228/-how-to-show-enable-location-dialog-like-google-maps

Onrush answered 26/4, 2015 at 1:34 Comment(28)
Hi Kai, can you show the complete logic, with its callbacks along with its implementation. I have tried this in Fragment class extending Map Class from Google. But i am getting Null Pointer result on PendingResults Array. Can you please guide?Empathic
The code above is the complete logic. The question is "How to show enable location dialog like Google maps?", but it appears your question is more about using embedded Google Maps, which is another question entirely. Please start a new question and I can try to answer (no promises though since I've never actually used embedded Google Maps)Onrush
You don't wait for the googleApiClient.connect(); to connect, do you?Aggappora
@MarianPaździoch pretty sure you don't need to, since Google's own sample code on SettingsApi doesn't require it.Onrush
Anyway in docs there is: "It does not need to be connected at the time of this call, but the result will be delayed until the connection is complete."Aggappora
@Onrush When I implement this code, pressing "No" on the dialog or pressing the native back button will not dismiss the dialog. It will continue showing the dialog until I either press "Yes" to enable location services, or close and re-open the app. Any idea how to fix that?Frosty
@Frosty never encountered this myself, are you running the code unmodified, and does it happen on all your devices?Onrush
@Onrush Yes, the code is unmodified on a Nexus 5. Using Logs, I see that when location services are initially off, it always hits RESOLUTION_REQUIRED. Then once I accept and enable location, it hits SUCCESS, and entirely skips onActivityResult(). Pressing No or back makes the dialog disappear for a second, then reload and hit RESOLUTION_REQUIRED again. The only way to get rid of the dialog is to either accept, or close and re-open the app.Frosty
@Frosty tested on Galaxy S4 with Google Play services 7.5.74 and it works, canceling doesn't cause RESOLUTION_REQUIRED to be called. My suggestion would be to update play services and try again. If that failed, start a new StackOverflow question to see if others have encountered and solved this issue.Onrush
@Onrush it worked for me but what if a user pressed no.How to show the dialog again or add some code there if pressed no.Any help will be highly appreciated.Ensign
@Onrush I want to show this dialog on button click,Is it possible to do? I tried but its not working.Squamous
Should i use google map api key for this.i am using this code but no dialogue is showing.i am getting this error in logcat..GoogleService failed to initialize, status: 10, Missing an expected resource: 'R.string.google_app_id' for initializing Google services. Possible causes are missing google-services.json or com.google.gms.google-services gradle plugin.Tolbert
@ExceptionLover no Google map API key is not required, since you are simply asking Google Play service to perform the changes for you. Your issue seem to be this.Onrush
@Squamous Assuming the status code is LocationSettingsStatusCodes.RESOLUTION_REQUIRED, you should be able to cache the status object and only call status.startResolutionForResult(getActivity(), 1000); on button click. If this is what you did and isn't working then I'd need more info, maybe start a new question if the info you'd need to provide is long.Onrush
I'm a bit confused. I displayed a map for my app and I even requested the Fine Location permissions without having a GoogleApiClient at all. However, when I click on the MyLocation button on the map nothing used to happen when you haven't turned on your location on the phone so I wanted to show this dialog. Why do I need to connect to the API just for that setting change?Edwin
@Edwin If the location setting of the phone is off, you don't get any location (it's off, remember?). To check for location setting you can either write your own code or use Google API as above, which is easier.Onrush
Okay thank you, another quick thing then, so is it possible to seemlessly stop the high accuracy the user allowed for us to use after the application is closed for example, so that the user doesn't have to stop it himself? Or can we use this high accuracy location without updating location based on frequency? what if we just need to know the current location once?Edwin
NOTE: your activity's launchMode can NOT be set to singleInstance otherwise this will NOT work. The dialog will never show up and onActivityResult will be called automatically. DO NOT HAVE android:launchMode="singleInstance" for your activity in AndroidManifest. I learned this very hard way after 3 hoursRicardo
hai can i customize dialog color?Academia
I would like to add here after the comment from th3patel. That if your activity has android:clearTaskOnLaunch="true" Then dialog will never show..Retiary
After changing LocationRequest priority from PRIORITY_LOW_POWER to PRIORITY_HIGH_ACCURACY, the dialog finally showed up. It just took me 5 hours to realize this. Perhaps, Google might want to consider to put some notes about this one?Legibility
This is asking for wifi/background scanning on my phone as well. Is there a way for it to just be GPS + data only?Embus
Hello, I have a issue, when I turn on GPS and try to load data second time, The map is not zooming at its particular location. Will anybody pls. see here : #44369460Meshuga
why on screenshot it says only "GPS use for location" when it should "GPS, Wi-Fi and mobile for locaiton" if you set LocationRequest.PRIORITY_HIGH_ACCURACY??Hifalutin
@Hifalutin that's the wording they used 2.5 years ago, may or may not be the same nowOnrush
Can I somehow change the text in that dialog? Or use my own dialog?Feder
add wrong tag supportlifecyclefragmentimpl using this dialog.Barter
how to handle "YES" and "NO" button click call back ?Freak
C
55

I would like to add up some changes to kai's answer for those who are looking for handling Yes/No buttons.

Declare this constant in your activity

protected static final int REQUEST_CHECK_SETTINGS = 0x1;

call settingsrequest() in your onStart()

public void settingsrequest()
    {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                final LocationSettingsStates state = 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(MainActivity.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        startLocationUpdates();
                        break;
                    case Activity.RESULT_CANCELED:
                        settingsrequest();//keep asking if imp or do whatever
                        break;
                }
                break;
        }
    }
Chally answered 14/10, 2015 at 9:33 Comment(10)
got from the official documentation: developers.google.com/android/reference/com/google/android/gms/… if you need to add only maps, to use this you have to add those libraries (without importing the entire play services library): compile 'com.google.android.gms:play-services-maps:9.0.2' compile 'com.google.android.gms:play-services-location:9.0.2'Turkestan
how to handle click event of this dialog and i must never show never button in dialogFruitcake
remove the settingsrequest() line from switch case in ActivityOnResult.. Is that what you are asking???Chally
If I click on no button of dialog still that dialog comes continuously.. I already remove the settingsrequest() line from switch case in ActivityOnResult.. then why it is showing continuously?Reins
May be u need to clean build the project.Chally
Which class is builder came from?Legibility
Builder is Implemented as Inner class of LocationSettingsRequest class, refer to the Documentation for more details : developers.google.com/android/reference/com/google/android/gms/…Chally
Hello, I have a issue, when I turn on GPS and try to load data second time, The map is not zooming at its particular location. Will anybody pls. see here : #44369460Meshuga
i think there is problem in your answer, you did not build GoogleApiClientSitsang
@DhruvTyagi my answer only aims at handling the dialog buttons if the users chooses not to share the location. building the GoogleApiClient is the pre requisite for this.Chally
K
28

LocationServices.SettingsApi is deprecated now, So We use SettingsClient

    LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setSmallestDisplacement(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new 
        LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);

Then check whether current location settings are satisfied. Create the LocationSettingsResponse task:

        Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());

Then add Listener

task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
            @Override
                    public void onComplete(Task<LocationSettingsResponse> task) {
                        try {
                            LocationSettingsResponse response = task.getResult(ApiException.class);
                            // All location settings are satisfied. The client can initialize location
                            // requests here.

                        } catch (ApiException exception) {
                            switch (exception.getStatusCode()) {
                                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                    // Location settings are not satisfied. But could be fixed by showing the
                                    // user a dialog.
                                    try {
                                        // Cast to a resolvable exception.
                                        ResolvableApiException resolvable = (ResolvableApiException) exception;
                                        // Show the dialog by calling startResolutionForResult(),
                                        // and check the result in onActivityResult().
                                        resolvable.startResolutionForResult(
                                                HomeActivity.this,
                                                101);
                                    } catch (IntentSender.SendIntentException e) {
                                        // Ignore the error.
                                    } catch (ClassCastException e) {
                                        // Ignore, should be an impossible error.
                                    }
                                    break;
                                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                    // Location settings are not satisfied. However, we have no way to fix the
                                    // settings so we won't show the dialog.
                                    break;
                            }
                        }
                    }
                });

Added onActivityResult

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) {
            case 101:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
                break;
        }
    }

Refer the link SettingsClient

Kho answered 11/6, 2018 at 10:58 Comment(4)
Check stackoverflow.com/a/53277287 @BadLoser Using SettingsClientDisjoined
What is the name of the dependency to import? Cannot resolve symbol Task.Headlock
I found it : implementation 'com.google.android.gms:play-services-tasks:16.0.1'Headlock
@Denis, I could use implementation 'com.google.android.gms:play-services-location:16.0.0' instead.Impercipient
W
25

Its Working similar to google maps?
Source Code: https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0

Add Dependency in build.gradle file:

compile 'com.google.android.gms:play-services:8.3.0'

OR

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

enter image description here

public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity {

    protected static final String TAG = "LocationOnOff";


    private GoogleApiClient googleApiClient;
    final static int REQUEST_LOCATION = 199;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setFinishOnTouchOutside(true);

        // Todo Location Already on  ... start
        final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE);
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
            finish();
        }
        // Todo Location Already on  ... end

        if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)){
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show();
        }

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) {
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show();
            enableLoc();
        }else{
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
        }
    }


    private boolean hasGPSDevice(Context context) {
        final LocationManager mgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (mgr == null)
            return false;
        final List<String> providers = mgr.getAllProviders();
        if (providers == null)
            return false;
        return providers.contains(LocationManager.GPS_PROVIDER);
    }

    private void enableLoc() {

        if (googleApiClient == null) {
            googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(Bundle bundle) {

                        }

                        @Override
                        public void onConnectionSuspended(int i) {
                            googleApiClient.connect();
                        }
                    })
                    .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) {

                            Log.d("Location error","Location error " + connectionResult.getErrorCode());
                        }
                    }).build();
            googleApiClient.connect();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);

            builder.setAlwaysShow(true);

            PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION);

                                finish();
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                    }
                }
            });
        }
    }

}
Waterfall answered 21/6, 2017 at 7:7 Comment(2)
See Broadcast Receiver Post Very Useful and Like me #15699290Waterfall
Can you please update the link, it's broken now, post the code in GitHub insteadRojas
H
7

Dependency

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

Code

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    public static final int REQUEST_LOCATION=001;

    GoogleApiClient googleApiClient;

    LocationManager locationManager;
    LocationRequest locationRequest;
    LocationSettingsRequest.Builder locationSettingsRequest;
    Context context;


    PendingResult<LocationSettingsResult> pendingResult;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show();

        } else {
            mEnableGps();
        }

    }

    public void mEnableGps() {
        googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        googleApiClient.connect();
        mLocationSetting();
    }

    public void mLocationSetting() {
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(1 * 1000);
        locationRequest.setFastestInterval(1 * 1000);

        locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);

        mResult();

    }

    public void mResult() {
        pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build());
        pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                Status status = locationSettingsResult.getStatus();


                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                        try {

                            status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
                        } catch (IntentSender.SendIntentException e) {

                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.


                        break;
                }
            }

        });
    }


    //callback method
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) {
            case REQUEST_LOCATION:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
                break;
        }
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}
Heraldic answered 21/7, 2017 at 12:56 Comment(0)
S
6

GoogleApiClient is deprecated. New implementation in Kotlin can be as following.

Dependencies

// Google Maps Location Services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'

Code

val locationRequest = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(30 * 1000)
    .setFastestInterval(5 * 1000)

val builder = LocationSettingsRequest.Builder()
    .addLocationRequest(locationRequest)
    .setAlwaysShow(true)

val pendingResult = LocationServices
    .getSettingsClient(activity)
    .checkLocationSettings(builder.build())

pendingResult.addOnCompleteListener { task ->
    if (task.isSuccessful.not()) {
        task.exception?.let {
            if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                (it as ResolvableApiException).startResolutionForResult(activity,
                    MainActivity.REQUEST_CODE_LOCATION)
            }
        }
    }
}
Swainson answered 23/10, 2020 at 8:36 Comment(2)
This answer can be checked as well: https://mcmap.net/q/168022/-locationsettingsrequest-dialog-to-enable-gps-onactivityresult-skippedSwainson
still good answer just change some codeLizarraga
N
4

You can also add several LocationRequests for Builder to achieve "Use GPS, Wi-Fi and mobile networks for location" dialog instead just "Use GPS for location"

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY))
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY))
                .setAlwaysShow(true);

PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
Numismatist answered 23/9, 2017 at 23:23 Comment(1)
In my case it is enough to use PRIORITY_HIGH_ACCURACY to get sentence "Use GPS, Wi-Fi and mobile networks for location". But it is strange that it works on real device but in simulator does not. In simulator sentence is always without "Use GPS" at the start although I see that simulator device has GPS.Drakensberg
C
3

In Kotlin, use this code:

import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.PendingResult
import com.google.android.gms.common.api.Status
import com.google.android.gms.location.*

class MainActivity : AppCompatActivity() {
    private var googleApiClient: GoogleApiClient? = null
    private val REQUESTLOCATION = 199
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableLoc()
    }
    private fun enableLoc() {
        googleApiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
                override fun onConnected(bundle: Bundle?) {}
                override fun onConnectionSuspended(i: Int) {
                    googleApiClient?.connect()
                }
            })
            .addOnConnectionFailedListener {
            }.build()
        googleApiClient?.connect()
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 30 * 1000.toLong()
        locationRequest.fastestInterval = 5 * 1000.toLong()
        val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
        builder.setAlwaysShow(true)
        val result: PendingResult<LocationSettingsResult> =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
        result.setResultCallback { result ->
            val status: Status = result.status
            when (status.statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                    status.startResolutionForResult(
                        this@MainActivity,
                        REQUESTLOCATION
                    )
                } catch (e: IntentSender.SendIntentException) {
                }
            }
        }
    }
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            REQUESTLOCATION -> when (resultCode) {
                Activity.RESULT_OK -> Log.d("abc","OK")
                Activity.RESULT_CANCELED -> Log.d("abc","CANCEL")
            }
        }
    }
}
Carbon answered 18/5, 2020 at 11:53 Comment(1)
GoogleApiClient is deprecated. what to use?Cynthiacynthie
P
3

This is my Kotlin example-

  private fun enableLocation() {
    val locationRequest = LocationRequest.create()
    locationRequest.apply {
        priority =LocationRequest.PRIORITY_HIGH_ACCURACY
        interval = 30 * 1000.toLong()
        fastestInterval = 5 * 1000.toLong()
    }
    val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
    builder.setAlwaysShow(true)
    val result=
            LocationServices.getSettingsClient(requireContext()).checkLocationSettings(builder.build())
    result.addOnCompleteListener {
        try {
            val response: LocationSettingsResponse = it.getResult(ApiException::class.java)
            println("location>>>>>>> ${response.locationSettingsStates.isGpsPresent}")
            if(response.locationSettingsStates.isGpsPresent)
                //do something
        }catch (e: ApiException){
            when (e.statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                    val intentSenderRequest =
                        IntentSenderRequest.Builder(e.status.resolution).build()
                    launcher.launch(intentSenderRequest)
                } catch (e: IntentSender.SendIntentException) {
                }
            }
        }
    }
}

And use below get Result method

 private var launcher=  registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()){ result->
  if (result.resultCode == Activity.RESULT_OK) {
      Log.d(TAG, "OK")
      
  } else {
      Log.d(TAG, "CANCEL")
      requireContext().toast("Please Accept Location enable for use this App.")
  }
}
Passementerie answered 31/8, 2021 at 15:37 Comment(0)
D
2

Please check my very simple solution to get the user location in the foreground.

  1. GPS Setting dialog
  2. User location with live data.
  3. LocationUtility class is activity life cycle aware to pause/resume the location updates.
  4. Location with the latest FusedLocationProviderClient

https://github.com/Maqsood007/UserLocation-Android/blob/master/app/src/main/java/jetpack/skill/userlocation_android/utils/LocationUtility.kt

enter image description here

enter image description here

Dimissory answered 23/7, 2020 at 23:7 Comment(0)
D
2

New updated answer August 2020 enter link description here

my fragment is like this update if u are using inside your activity

 import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;


import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;

import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;

import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class FragmentSearch extends Fragment
{

    View SearchFragmentview;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false);

           getLocationDialog();

        return  SearchFragmentview;

    }

    private void getLocationDialog()
    {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build());



        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>()
        {
            @Override
            public void onComplete(Task<LocationSettingsResponse> task)
            {
                try {
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                }
                catch (ApiException exception)
                {
                    switch (exception.getStatusCode())
                    {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the
                            // user a dialog.
                            try {
                                // Cast to a resolvable exception.
                                ResolvableApiException resolvable = (ResolvableApiException) exception;
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().


                                resolvable.startResolutionForResult(
                                      getActivity(),
                                        REQUEST_CHECK_SETTINGS);

                            }
                            catch (IntentSender.SendIntentException e)
                            {
                                // Ignore the error.
                            }
                            catch (ClassCastException e)
                            {
                                // Ignore, should be an impossible error.
                            }
                            break;
                           case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.

                            break;
                    }
                }
            }
        });


    }



    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        switch (requestCode)
        {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode)
                {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made

                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to

                        break;
                    default:
                        break;
                }
                break;
        }
    }[enter image description here][2]



}
Dowager answered 11/8, 2020 at 1:4 Comment(0)
Z
0

Settings api deprecated use this.

   private void openDeviceLocationRequest() {
        if (!locationPermissionGranted)
            return;

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
        result.addOnCompleteListener(task -> {
            try {
                LocationSettingsResponse response = task.getResult(ApiException.class);
                // All location settings are satisfied. The client can initialize location
                // requests here.
                if(lastKnownLocation == null)
                getDeviceLocation();

            } catch (ApiException exception) {
                switch (exception.getStatusCode()) {
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the
                        // user a dialog.
                        try {
                            // Cast to a resolvable exception.
                            ResolvableApiException resolvable = (ResolvableApiException) exception;
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            resolvable.startResolutionForResult(
                                    MapAddressActivity.this,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        } catch (ClassCastException e) {
                            // Ignore, should be an impossible error.
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                }
            }
        });
    }
Zacheryzack answered 9/7, 2021 at 8:7 Comment(0)
M
0

implementation 'com.google.android.gms:play-services-location:18.0.0'

private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private static final int REQUEST_CHECK_SETTINGS = 214;
    private static final int REQUEST_ENABLE_GPS = 516;



 LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
        builder.setAlwaysShow(true);
        mLocationSettingsRequest = builder.build();

        mSettingsClient = LocationServices.getSettingsClient(MainActivity.this);

        mSettingsClient
                .checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                        //Success Perform Task Here
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                try {
                                    ResolvableApiException rae = (ResolvableApiException) e;
                                    rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                                } catch (IntentSender.SendIntentException sie) {
                                    Log.e("GPS","Unable to execute request.");
                                }
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                Log.e("GPS","Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
                        }
                    }
                })
                .addOnCanceledListener(new OnCanceledListener() {
                    @Override
                    public void onCanceled() {
                        Log.e("GPS","checkLocationSettings -> onCanceled");
                    }
                });
Moynihan answered 14/9, 2021 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.