62

I am working on map related android application and I need to check location access enable or not in client side development if location services is not enable show the dialog prompt.

How to enable "Location access" Programmatically in android?

Cœur
  • 37,241
  • 25
  • 195
  • 267
NarasimhaKolla
  • 791
  • 3
  • 7
  • 14

7 Answers7

128

Use below code to check. If it is disabled, dialog box will be generated

public void statusCheck() {
    final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        buildAlertMessageNoGps();

    }
}

private void buildAlertMessageNoGps() {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
            .setCancelable(false)
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog, final int id) {
                    startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog, final int id) {
                    dialog.cancel();
                }
            });
    final AlertDialog alert = builder.create();
    alert.show();
}
ᴛʜᴇᴘᴀᴛᴇʟ
  • 4,466
  • 5
  • 39
  • 73
Gautam
  • 3,252
  • 3
  • 23
  • 32
  • Hi above code is working fine but one small issue after enable the location services how to redirect my current page? – NarasimhaKolla Aug 07 '14 at 07:20
  • Use Intent like below- Intent i = new Intent(Yourclassname.this,ClassToReach.class); startActivity(i); – Gautam Aug 07 '14 at 07:33
  • 5
    I think, this is not correct answer, because @NarasimhaKolla want to activate Location Service. First you need to write what really want to activate Network or GPS provider? This solution, check is GPS activated, but what if user has activated "Device only" mode. What if user is on Wi-Fi and he is inside building, you will try to find location via GPS provider, i think user never receive location, only if user is so close window... My answer: on "Mobile Data" check GPS and Network provider, on "WiFi" check and require only Network provider. Sorry about english :) – Sinan Dizdarević Jan 11 '15 at 01:47
  • @Gautam this answer helped me. Please clarify how to return to Activity, I tried your suggestion using `Intent` but app craches (NullPointerException on Location) . I'm trying to make app work as smoothly as it does if Location Service was initially enabled. – Emzor Jan 14 '16 at 14:10
  • 3
    you can't automatically redirect user to come to your activity, but in most cases user will be pressing back button and you can catch the action if you use - startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 1); & check the resultcode in onActivityResult. Hope it clears your doubt – Gautam Jan 14 '16 at 17:55
  • but if I want to enable without going to settings page as mentioned in updated play services ,can i do it in my own custom dialog – Srishti Roy Feb 08 '16 at 13:33
  • @SrishtiRoy now you can do that using SettingsApi . You can refer the developers doc for the same https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi – Gautam Feb 10 '16 at 06:57
  • is fine in 23 version also,run time permissions implementation little hard for me – Harsha Sep 27 '16 at 06:00
15

Here is a simple way of programmatically enabling location like Maps app:

protected void enableLocationSettings() {
       LocationRequest locationRequest = LocationRequest.create()
             .setInterval(LOCATION_UPDATE_INTERVAL)
             .setFastestInterval(LOCATION_UPDATE_FASTEST_INTERVAL)
             .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

        LocationServices
                .getSettingsClient(this)
                .checkLocationSettings(builder.build())
                .addOnSuccessListener(this, (LocationSettingsResponse response) -> {
                    // startUpdatingLocation(...);
                })
                .addOnFailureListener(this, ex -> {
                    if (ex instanceof ResolvableApiException) {
                        // Location settings are NOT satisfied,  but this can be fixed  by showing the user a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),  and check the result in onActivityResult().
                            ResolvableApiException resolvable = (ResolvableApiException) ex;
                            resolvable.startResolutionForResult(TrackingListActivity.this, REQUEST_CODE_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException sendEx) {
                            // Ignore the error.
                        }
                    }
                });
 }

And onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    if (REQUEST_CODE_CHECK_SETTINGS == requestCode) {
        if(Activity.RESULT_OK == resultCode){
            //user clicked OK, you can startUpdatingLocation(...);

        }else{
            //user clicked cancel: informUserImportanceOfLocationAndPresentRequestAgain();
        }
    }
}

You can see the documentation here: https://developer.android.com/training/location/change-location-settings

makata
  • 2,188
  • 2
  • 28
  • 23
  • 1
    Yes! This is similar to Google Maps app showing small dialog with OK and Cancel button to enable GPS without navigating away from app. – KSK Feb 25 '21 at 09:25
  • Thanks It is working. How to disable "No thanks" button from dialog? I want to restrict only yes selection option or automatically enable location service? Is it possible? – TejpalBh Mar 08 '21 at 05:46
  • @TejpalBh that is not possible with this approach! And, what you are looking for is a bad design ... – makata Apr 08 '21 at 17:58
  • the drawback of this is that you need google services location library when its needed just to have location turned on for nearby scan – Ultimo_m Nov 09 '22 at 13:56
9

You can try these methods below:

To check if GPS and network provider is enabled:

public boolean canGetLocation() {
    boolean result = true;
    LocationManager lm;
    boolean gpsEnabled = false;
    boolean networkEnabled = false;

    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // exceptions will be thrown if provider is not permitted.
    try {
        gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
    }

    try {
        networkEnabled = lm
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    return gpsEnabled && networkEnabled;
}

Alert Dialog if the above code returns false:

public void showSettingsAlert() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

    // Setting Dialog Title
    alertDialog.setTitle("Error!");

    // Setting Dialog Message
    alertDialog.setMessage("Please ");

    // On pressing Settings button
    alertDialog.setPositiveButton(
            getResources().getString(R.string.button_ok),
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(intent);
                }
            });

    alertDialog.show();
}

How to use the two methods above:

if (canGetLocation()) {     
    //DO SOMETHING USEFUL HERE. ALL GPS PROVIDERS ARE CURRENTLY ENABLED                 
} else {
    //SHOW OUR SETTINGS ALERT, AND LET THE USE TURN ON ALL THE GPS PROVIDERS                                
    showSettingsAlert();
}
Anirban Das
  • 1,035
  • 1
  • 18
  • 22
icaneatclouds
  • 1,170
  • 9
  • 18
  • 3
    How about less code: `return gps_enabled || network_enabled;`. Also you may want to follow the naming guidelines and use camelCase instead: `return gpsEnabled || networkEnabled;` – Michel Jung Jan 27 '15 at 15:34
  • @MichelJung I think it will be `return gps_enabled && network_enabled;`. – Anirban Das Aug 08 '20 at 09:17
3

just checkout the following thread: How to check if Location Services are enabled? It provides a pretty good example of how to check whether the location service was enabled or not.

Community
  • 1
  • 1
schneiti
  • 428
  • 1
  • 8
  • 22
3
private ActivityResultLauncher<IntentSenderRequest> resolutionForResult;

resolutionForResult = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
        if(result.getResultCode() == RESULT_OK){
            //Granted
        }else {
            //Not Granted
        }
    });

    private void enableLocationSettings() {
    LocationRequest locationRequest = LocationRequest.create()
            .setInterval(10 * 1000)
            .setFastestInterval(2 * 1000)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

    LocationServices
            .getSettingsClient(requireActivity())
            .checkLocationSettings(builder.build())
            .addOnSuccessListener(requireActivity(), (LocationSettingsResponse response) -> {
                // startUpdatingLocation(...);
            })
            .addOnFailureListener(requireActivity(), ex -> {
                if (ex instanceof ResolvableApiException) {
                    try{
                        IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(((ResolvableApiException) ex).getResolution()).build();
                        resolutionForResult.launch(intentSenderRequest);
                    }catch (Exception exception){
                        Log.d(TAG, "enableLocationSettings: "+exception);
                    }
                }
            });
}
EhtA Sham
  • 31
  • 1
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 23 '21 at 08:38
1

With recent Marshmallow update, even when the Location setting is turned on, your app will require to explicitly ask for permission. The recommended way to do this is to show the Permissions section of your app wherein the user can toggle the permission as required. The code snippet for doing this is as below:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    
    if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Location Permission");
        builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app.");
        builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
    
            }
        });
        builder.setNegativeButton(android.R.string.no, null);
        builder.show();
    }
} else {
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean isGpsProviderEnabled, isNetworkProviderEnabled;
    isGpsProviderEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    isNetworkProviderEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    if(!isGpsProviderEnabled && !isNetworkProviderEnabled) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Location Permission");
        builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app.");
        builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        });
        builder.setNegativeButton(android.R.string.no, null);
        builder.show();
    }
}

And override the onRequestPermissionsResult method as below:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_COARSE_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "coarse location permission granted");
            } else {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            }
        }
    }
}

Another approach is you can also use the SettingsApi to inquire which location provider(s) are enabled. If none is enabled, you can prompt a dialog to change the setting from within the app.

Mahendra Liya
  • 12,912
  • 14
  • 88
  • 114
-1

Taking the answer above and converting it to Kotlin

fun isLocationEnabled(): Boolean {
    val lm = getSystemService(LOCATION_SERVICE) as LocationManager
    // exceptions will be thrown if provider is not permitted.
    val gpsEnabled = try {
        lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
    } catch (ex: java.lang.Exception) {
        false
    }
    val networkEnabled = try {
        lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
    } catch (ex: java.lang.Exception) {
        false
    }
    return gpsEnabled && networkEnabled
}
Kevin
  • 1,405
  • 15
  • 16