How can I enable or disable the GPS programmatically on Android?
Asked Answered
P

17

173

I know that the question about turning on/off GPS programatically on android has been discussed many times, and the answer is always the same:

"You can't for security/privacy reasons, you have to forward to location preferences screen and let the user enable/disable it."

I understand that, however I recently bought Tasker from the market and, among many other things that you can accomplish with it, you can set rules to auto-enable GPS on entering pre-determined applications and disable it on exit (see here for the tutorial on how to do it, and it just works!) and this app can't be signed with the firmware signing key as it works on many android versions and different devices and you don't even need to be rooted.

I would like to do this in my app. Of course, I don't want to blow up the users privacy, so I would first ask the user if he wants to turn it on automatically with the typical "remember my decision" checkbox and if he answers yes, enable it.

Does anybody have any idea or clue on how Tasker achieves this?

Pollen answered 18/1, 2011 at 7:23 Comment(1)
I want to turn GPS off and on so I can write tests on code that demands it's on. Without mocks, because Android makes those a painSpecialism
G
160

the GPS can be toggled by exploiting a bug in the power manager widget. see this xda thread for discussion.

here's some example code i use

private void turnGPSOn(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(!provider.contains("gps")){ //if gps is disabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); 
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

private void turnGPSOff(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(provider.contains("gps")){ //if gps is enabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

use the following to test if the existing version of the power control widget is one which will allow you to toggle the gps.

private boolean canToggleGPS() {
    PackageManager pacman = getPackageManager();
    PackageInfo pacInfo = null;

    try {
        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
    } catch (NameNotFoundException e) {
        return false; //package not found
    }

    if(pacInfo != null){
        for(ActivityInfo actInfo : pacInfo.receivers){
            //test if recevier is exported. if so, we can toggle GPS.
            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
                return true;
            }
        }
    }

    return false; //default
}
Gent answered 14/3, 2011 at 23:26 Comment(19)
hmmm interesting... I was sure it would not be a very "legal" way to do this... thanks!Pollen
At the time of this (my) comment, the links in this answer seem to indicate that the bug this exploits has recently been fixed. I just wanted to point out that the exploit still seems to work just fine in my own test environment, so you shouldn't give up on trying this... just be sure that your code will handle any errors if it doesn't work!Banded
As of this comment's writing, this exploit still works on a 2.2.1 Android phone. Nice find, Ben H.Kyliekylila
yes, the bug was supposedly fixed in android 2.3. however, some custom 2.3+ ROMs include the unfixed version of the power control widget, so it works on them.Gent
Hello , here com.android.settings is app Package name or what ?Squib
yes, that is the package that contains the power control widget.Gent
Anyone know the status of this with honeycomb and ICS?Chaffin
It turns on GPS as displayed in Settings, but when I try to get a location from GPS provider, it doesn't give me any new locations.Chela
any solution to ON GPS for versions above: 2.2Pun
Is there ay way to tirn on aGPS... Is the way similar! Ben thanks, it really works!Benne
aGPS can't be turned on or off. it's dependent on GPS, so if GPS is off, then aGPS isn't available either. are you perhaps asking about cell tower location instead? that should be active by default as long as the phone isn't in airplane mode.Gent
what if i have root permission for my app? is it possible to use it in order to toggle gps on/off without using the exploit , even on newer android versions?Igorot
i don't believe so. if your app is installed as a system app (in /system/app), then you can use the WRITE_SECURE_SETTINGS permission and the Settings.Secure class to toggle the GPS. root alone is not going to give you WRITE_SECURE_SETTINGS. this is just a guess, but you might be able to edit the settings database (settings.db) using sqlite and root.Gent
This is a really bad idea. Once the bug gets fixed, your exploit will no longer work. Better to just send the user to the settings app.Glyptography
Working fine in Android 2.3.6 but not working android 4.0.3 . Any idea to enable or disable in android 4.0.3Deictic
hahaha... this exploit reemerged in 4.2.2, Surprised to see it.. GOD!Cressler
It's not a feasible solution any more. Seems android has fixed that issue, so it looks like working in bar but it's hardware is still OFF and won't through any locations except value 0.0 in both lat & lon.Nuptial
Settings.Secure.LOCATION_PROVIDERS_ALLOWED is deprecated on KITKAT. This is the time when this trick doesn't work any more.Prog
its not working , when this code executed for disabling gps BUT when i check manually i see gps is enable not disable. Please help me to resolve this.Thanks in advance!Agave
C
77

All these answers are not allowed now. Here is the correct one:

For all those still looking for the Answer:

Here is how OLA Cabs and other such apps are doing it.

Add this in your onCreate

if (googleApiClient == null) {
    googleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(Login.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(Login.this, 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;
            }
        }
    });
}

These are the implmented methods:

@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionSuspended(int arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub

}

Here is the Android Documentation for the same.

This is to help other guys if they are still struggling:

Edit: Adding Irfan Raza's comment for more help.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == 1000) {
         if(resultCode == Activity.RESULT_OK){
             String result=data.getStringExtra("result"); 
         } if (resultCode == Activity.RESULT_CANCELED) {
             //Write your code if there's no result 
         } 
    } 
} 
Compressed answered 5/11, 2015 at 22:9 Comment(12)
Now this answer should be the accepted one. Thanks a lot Akshat!!Lancelot
Needs Google API client integration hence only a solution for specific use cases, not fit for a generic solution.Levon
@DilroopSingh what problem are you facing.? I am using the same code and it works perfectly.Compressed
can we achieve this without showing that builder.Because i need to turn on gps without showing any alerts.Diaspora
@Diaspora Thats not possible. User consent is must and thus that builder has to be shown.Compressed
Yes, i know that but i wanted to track the user without knowing him.Diaspora
Thanks @Akshat. Its working at my end. But onConnected method always fires even before the popup appears. So basically irrespective of whether user allows Ok or cancel the consent, onConnected gets called with bundle as null. Is there any way that I can get to know when user has clicked the OK button?, so I can do further processing.Menefee
I figured it out. It was very simple. This is to help other guys if they are still struggling: @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1000) { if(resultCode == Activity.RESULT_OK){ String result=data.getStringExtra("result"); } if (resultCode == Activity.RESULT_CANCELED) { //Write your code if there's no result } } }Menefee
Where do i have to put this code? I had put it in onStart()..but not receiving any update in on location changed Listener.Dyke
This answer is also deprecated now. Check here : developers.google.com/android/reference/com/google/android/gms/…Clement
does this method still work ? I need a valid response.Ellisellison
How to stop location update once we get it so that power consumption can be reducedMutate
L
50

ENABLE GPS:

Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);

DISABLE GPS:

Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
Letourneau answered 16/7, 2012 at 11:14 Comment(7)
automatically GPS will turn on/off.Letourneau
This also helps to enable. private void turnGPSOn(){ String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if(!provider.contains("gps")){ //if gps is disabled final Intent poke = new Intent(); poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); poke.addCategory(Intent.CATEGORY_ALTERNATIVE); poke.setData(Uri.parse("3")); sendBroadcast(poke); } }Letourneau
in android 2.3.4 running on asamsung sII it turns the gps icon on without effectively activating the gps sensor. But, if you choose to turn the GPS sensor on programmatically, it is then recognized.Gascon
android 4.0.4 - only gps notification is enabled. not the gps itself. so it looks like it's on but in fact it's notVaca
@alex: For security reasons I hope the opposite is not possible. Namely to query location (GPS or A-GPS) but suppress the UI notification for it. Or is it possible?Unbutton
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGEExperientialism
It not work and show this error: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGERyon
G
28

This code works on ROOTED phones if the app is moved to /system/aps, and they have the following permissions in the manifest:

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>

Code

private void turnGpsOn (Context context) {
    beforeEnable = Settings.Secure.getString (context.getContentResolver(),
                                              Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    String newSet = String.format ("%s,%s",
                                   beforeEnable,
                                   LocationManager.GPS_PROVIDER);
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   newSet); 
    } catch(Exception e) {}
}


private void turnGpsOff (Context context) {
    if (null == beforeEnable) {
        String str = Settings.Secure.getString (context.getContentResolver(),
                                                Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        if (null == str) {
            str = "";
        } else {                
            String[] list = str.split (",");
            str = "";
            int j = 0;
            for (int i = 0; i < list.length; i++) {
                if (!list[i].equals (LocationManager.GPS_PROVIDER)) {
                    if (j > 0) {
                        str += ",";
                    }
                    str += list[i];
                    j++;
                }
            }
            beforeEnable = str;
        }
    }
    try {
        Settings.Secure.putString (context.getContentResolver(),
                                   Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                                   beforeEnable);
    } catch(Exception e) {}
}
Genic answered 22/9, 2013 at 16:48 Comment(7)
+1 for mentioning this method. It should work with a system-app on a nonrooted device as well.Trumpetweed
this is the right way. Works on every version of Android, no need any trick!Waterhouse
turning off gps is not working!! can you please tell me why and the possible solution.Loney
now the gps is turning off and on perfectly but GPS is not working, i.e. giving location lat long 0.0Loney
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> only for the system apsBlackguardly
@Genic where do i call this method? In splash? isn't there a way the gps will turn on automatically at the time of installing?Detent
Its just triggered animation Wifi Toogle, but actually not triggered Google Location Service.Outland
P
27

Instead of using intent Settings.ACTION_LOCATION_SOURCE_SETTINGS you can directly able to show pop up in your app like Google Map & on Gps on click of ok button their is no need to redirect to setting simply you need to use my code as

Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also

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


LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;

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

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    mGoogleApiClient.connect();

}

@Override
public void onConnected(Bundle bundle) {

    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(30 * 1000);
    mLocationRequest.setFastestInterval(5 * 1000);

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);
    builder.setAlwaysShow(true);

    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_LOCATION);
                    } catch (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
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    Log.d("onActivityResult()", Integer.toString(resultCode));

    //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(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
                    break;
                }
                case Activity.RESULT_CANCELED:
                {
                    // The user was asked to change settings, but chose not to
                    Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
    }
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}
} 

Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also

Prairial answered 2/3, 2017 at 13:21 Comment(2)
this code is working fine but don't forgot location permission and playservice jar in gradle file ...Rosetterosewall
How can one do this in Compose apps with no access to onActivityResult?Quinlan
C
23

Since Android version 4.4, you can't enable/disable gps programatically. If you try the code proposed on this answer, an exception will be fired.

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
Chloric answered 4/8, 2014 at 19:35 Comment(2)
So is it a comment or else what is the solution?Alltime
@Shylendra Madda There is no solution for enabling GPS. You only can invoke the corresponding system dialog.Parvis
H
11

Above correct answer is very old it needs something new so Here is answer

As in last update we have androidx support so first include dependency in your app level build.gradle file

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

then add in your manifest file:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

don't forget to take user consent for these permissions if you are releasing

now here is code just use it

 protected void createLocationRequest() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setInterval(10000);
    locationRequest.setFastestInterval(5000);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

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



    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
        @Override
        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
            // All location settings are satisfied. The client can initialize
            // location requests here.
            // ...

            Toast.makeText(MainActivity.this, "Gps already open", 
                                          Toast.LENGTH_LONG).show();
            Log.d("location settings",locationSettingsResponse.toString());
        }
    });

    task.addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            if (e 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) e;
                    resolvable.startResolutionForResult(MainActivity.this,
                            REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException sendEx) {
                    // Ignore the error.
                }
            }
        }
    });
}


@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode==REQUEST_CHECK_SETTINGS){

        if(resultCode==RESULT_OK){

            Toast.makeText(this, "Gps opened", Toast.LENGTH_SHORT).show();
            //if user allows to open gps
            Log.d("result ok",data.toString());

        }else if(resultCode==RESULT_CANCELED){

            Toast.makeText(this, "refused to open gps", 
                                         Toast.LENGTH_SHORT).show();
            // in case user back press or refuses to open gps
            Log.d("result cancelled",data.toString());
        }
    }
}

if something goes wrong please ping me

Heartbreaker answered 21/7, 2019 at 3:19 Comment(0)
M
7

Short and easy solution with newest API, from https://developer.android.com/training/location/change-location-settings.html.

You will get nice Google AlertDialog with ok button without any need of going to settings.

Straight to the point. My code in Fragment:

override fun onResume() {
        super.onResume()
        checkGPSEnabled()
    }
private fun checkGPSEnabled() {
        val manager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER).not()) {
            turnOnGPS()
        }
    }
private fun turnOnGPS() {
        val request = LocationRequest.create().apply {
            interval = 2000
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }
        val builder = LocationSettingsRequest.Builder().addLocationRequest(request)
        val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
        val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
        task.addOnFailureListener {
            if (it is ResolvableApiException) {
                try {
                    it.startResolutionForResult(requireActivity(), 12345)
                } catch (sendEx: IntentSender.SendIntentException) {
                }
            }
        }.addOnSuccessListener {
            //here GPS is On
        }
    }

That's it. Just copy and paste. You will need also: implementation 'com.google.android.gms:play-services-location:18.0.0' and in Manifest <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Miguel answered 19/6, 2021 at 17:19 Comment(0)
Z
4

This code works on ROOTED phones:

public class MainActivity extends AppCompatActivity {

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

        String[] cmds = {"cd /system/bin" ,"settings put secure location_providers_allowed +gps"};
        try {
            Process p = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : cmds) {
                os.writeBytes(tmpCmd + "\n");
            }
            os.writeBytes("exit\n");
            os.flush();
        }
        catch (IOException e){
            e.printStackTrace();
        }
    }
}

For turning off GPS you can use this command instead

settings put secure location_providers_allowed -gps

You can also toggle network accuracy using the following commands: for turning on use:

settings put secure location_providers_allowed +network

and for turning off you can use:

settings put secure location_providers_allowed -network
Zoon answered 30/12, 2016 at 13:19 Comment(0)
W
2

An answer was developed in another question, but it was closed, and I'd like the community to try it out as well.

boolean gpsStatus = locmanager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsStatus) {
    Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network,gps");
}

See this comment

This solution would require the WRITE_SETTINGS and WRITE_SECURE_SETTINGS permissions.

Wigwam answered 18/1, 2011 at 7:23 Comment(6)
@milind , suppose i have a rooted device , what should i do in order to use this code? i've tried to get a root permission for the app , but it didn't help . it keeps saying "Permission denial: writing to secure settings requires android.permission.WRITE_SECURE_SETTINGS"Igorot
@android Read the last sentence of this post. Using this method will require the android.permission.WRITE_SECURE_SETTINGS permission in the Manifest.Wigwam
i know . i've already added it . it tells me that even though it's already in the manifest.Igorot
@android It looks like you're not the first one to have this problemWigwam
so it's impossible even for rooted devices?!Igorot
@androiddeveloper you can convert your application into System app and try this..this snippet will work!Andrade
K
2

Maybe with reflection tricks around the class android.server.LocationManagerService.

Also, there is a method (since API 8) android.provider.Settings.Secure.setLocationProviderEnabled

Kolk answered 18/1, 2011 at 14:19 Comment(2)
This Settings.Secure class seems promising, however I get a security exception saying that I need android.permission.WRITE_SECURE_SETTINGS, and I keep getting the error even adding this permission (and WRITE_SETTINGS also) to my manifest. But it seems a good way to keep searching. Thanks :)Pollen
WRITE_SECURE_SETTINGS has a protection level of systemOrSignature you need to make that app a system app for it to work, which is also mentioned in this answer.Keratose
P
2

This is the best solution provided by Google Developers. Simply call this method in onResume of onCreate after initializing GoogleApiClient.

private void updateMarkers() {
    if (mMap == null) {
        return;
    }

    if (mLocationPermissionGranted) {
        // Get the businesses and other points of interest located
        // nearest to the device's current location.
         mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).build();
        mGoogleApiClient.connect();
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(10000 / 2);

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


        LocationSettingsRequest.Builder builder = new LocationSettingsRequest
                .Builder()
                .addLocationRequest(mLocationRequest);
        PendingResult<LocationSettingsResult> resultPendingResult = LocationServices
                .SettingsApi
                .checkLocationSettings(mGoogleApiClient, builder.build());

        resultPendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                final Status status = locationSettingsResult.getStatus();
                final LocationSettingsStates locationSettingsStates = locationSettingsResult.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 this can 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,
                                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
                        } 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;
                }

            }
        });


        @SuppressWarnings("MissingPermission")
        PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
                .getCurrentPlace(mGoogleApiClient, null);
        result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
            @Override
            public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) {
                for (PlaceLikelihood placeLikelihood : likelyPlaces) {
                    // Add a marker for each place near the device's current location, with an
                    // info window showing place information.
                    String attributions = (String) placeLikelihood.getPlace().getAttributions();
                    String snippet = (String) placeLikelihood.getPlace().getAddress();
                    if (attributions != null) {
                        snippet = snippet + "\n" + attributions;
                    }

                    mMap.addMarker(new MarkerOptions()
                            .position(placeLikelihood.getPlace().getLatLng())
                            .title((String) placeLikelihood.getPlace().getName())
                            .snippet(snippet));
                }
                // Release the place likelihood buffer.
                likelyPlaces.release();
            }
        });
    } else {
        mMap.addMarker(new MarkerOptions()
                .position(mDefaultLocation)
                .title(getString(R.string.default_info_title))
                .snippet(getString(R.string.default_info_snippet)));
    }
}

Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also

 status.startResolutionForResult(
 MainActivity.this,
 PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
Puissance answered 29/11, 2016 at 7:49 Comment(3)
What is mLocationPermissionGranted?Benefic
that is for checking if the permission is granted or not for Location. this is run time permission granted.Puissance
you can also go through by simply setting the value true, if you already granted the permission on pre-lollipop devicePuissance
M
2

This one works for me.

It is a simpler solution than Rj0078's answer under this question, but that one is worked as well.

It shows a dialog like this:

enter image description here

(Written in Kotlin)

    googleApiClient = GoogleApiClient.Builder(context!!)
        .addApi(LocationServices.API).build()
    googleApiClient!!.connect()
    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)

    result =
       LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
    result!!.setResultCallback { result ->
        val status: Status = result.status
        when (status.statusCode) {
            LocationSettingsStatusCodes.SUCCESS -> {
               // Do something
            }
            LocationSettingsStatusCodes.RESOLUTION_REQUIRED ->
                try {
                    startResolutionForResult(),
                    status.startResolutionForResult(
                        activity,
                        REQUEST_LOCATION
                    )
                } catch (e: SendIntentException) {
                }
            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                // Do something
            }
        }
    }
Maxinemaxiskirt answered 20/3, 2020 at 13:25 Comment(0)
W
1

Things have changed since this question was posted, now with new Google Services API, you can prompt users to enable GPS:

https://developers.google.com/places/android-api/current-place

You will need to request ACCESS_FINE_LOCATION permission in your manifest:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Also watch this video:

https://www.youtube.com/watch?v=F0Kh_RnSM0w

Whipstitch answered 14/1, 2016 at 21:49 Comment(1)
Thanks. But the Google Play Services 7 can be used with old android versions? (API 14 - 23)Vaunt
F
1

This is a more statble code for all Android versions and possibly for new ones

void checkGPS() {
    LocationRequest locationRequest = LocationRequest.create();

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

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

    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
        @Override
        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
            Log.d("GPS_main", "OnSuccess");
            // GPS is ON
        }
    });

    task.addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull final Exception e) {
            Log.d("GPS_main", "GPS off");
            // GPS off
            if (e instanceof ResolvableApiException) {
                ResolvableApiException resolvable = (ResolvableApiException) e;
                try {
                    resolvable.startResolutionForResult(ActivityMain.this, REQUESTCODE_TURNON_GPS);
                } catch (IntentSender.SendIntentException e1) {
                    e1.printStackTrace();
                }
            }
        }
    });
}

And you can handle the GPS state changes here

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == Static_AppVariables.REQUESTCODE_TURNON_GPS) {
        switch (resultCode) {
            case Activity.RESULT_OK:
                // GPS was turned on;
                break;
            case Activity.RESULT_CANCELED:
                // User rejected turning on the GPS
                break;
            default:
                break;
        }
    }
}
Flavescent answered 9/10, 2020 at 17:29 Comment(0)
R
0

You just need to remove the LocationListener from LocationManager

manager.removeUpdates(listener);
Raoul answered 5/10, 2018 at 18:34 Comment(0)
M
0

Use This code Simple and Easy to Access:

Permissions:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Follow this Code to access the GPS programmatically:

LocationManager locationManager ;
 boolean GpsStatus ;


            GPSStatus();

            if(GpsStatus == true)
            {
                textview.setText("Your Location Services Is Enabled");
            }else
                {textview.setText("Your Location Services Is Disabled");}

            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);


    public void GPSStatus(){
    locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    GpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} 
Melanoma answered 8/2, 2019 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.