share
Stack OverflowHow can I enable or disable the GPS programmatically on Android?
[+170] [18] maid450
[2011-01-18 07:23:03]
[ android gps ]
[ https://stackoverflow.com/questions/4721449/how-can-i-enable-or-disable-the-gps-programmatically-on-android ]

I know that the question about turning on/off GPS programatically on android has [1] been [2] discussed [3] many [4] times [5], 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 [6] 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 [7] 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?

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 pain - Phlip
[+160] [2011-03-14 23:26:50] Ben H [ACCEPTED]

the GPS can be toggled by exploiting [1] a bug in the power manager widget. see this xda thread [2] 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
}
[1] http://code.google.com/p/android/issues/detail?id=7890
[2] http://forum.xda-developers.com/showthread.php?t=697465

hmmm interesting... I was sure it would not be a very "legal" way to do this... thanks! - maid450
(4) 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! - SilithCrowe
(1) As of this comment's writing, this exploit still works on a 2.2.1 Android phone. Nice find, Ben H. - Qix - MONICA WAS MISTREATED
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. - Ben H
Hello , here com.android.settings is app Package name or what ? - Girish Patel
yes, that is the package that contains the power control widget. - Ben H
Anyone know the status of this with honeycomb and ICS? - Patrick Jackson
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. - amit
any solution to ON GPS for versions above: 2.2 - Aakash
Is there ay way to tirn on aGPS... Is the way similar! Ben thanks, it really works! - timonvlad
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. - Ben H
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? - android developer
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. - Ben H
(52) 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. - Edward Falk
(1) Working fine in Android 2.3.6 but not working android 4.0.3 . Any idea to enable or disable in android 4.0.3 - Krishna
(5) hahaha... this exploit reemerged in 4.2.2, Surprised to see it.. GOD! - amithgc
(1) 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. - Harpreet
(1) Settings.Secure.LOCATION_PROVIDERS_ALLOWED is deprecated on KITKAT. This is the time when this trick doesn't work any more. - Shnkc
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! - Gyan Swaroop Awasthi
1
[+76] [2015-11-05 22:09:37] Akshat

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 [1] 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 
         } 
    } 
} 
[1] https://developer.android.com/training/location/change-location-settings.html

Now this answer should be the accepted one. Thanks a lot Akshat!! - Gurpreet
(2) Needs Google API client integration hence only a solution for specific use cases, not fit for a generic solution. - Cik
@DilroopSingh what problem are you facing.? I am using the same code and it works perfectly. - Akshat
(1) can we achieve this without showing that builder.Because i need to turn on gps without showing any alerts. - Punithapriya
(3) @Punithapriya Thats not possible. User consent is must and thus that builder has to be shown. - Akshat
Yes, i know that but i wanted to track the user without knowing him. - Punithapriya
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. - Irfan Raza
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 } } } - Irfan Raza
Where do i have to put this code? I had put it in onStart()..but not receiving any update in on location changed Listener. - Umesh Chauhan
This answer is also deprecated now. Check here : developers.google.com/android/reference/com/google/android/g‌​ms/… - Vaibhav Jani
does this method still work ? I need a valid response. - Naveen Niraula
How to stop location update once we get it so that power consumption can be reduced - Ankit Mishra
2
[+50] [2012-07-16 11:14:35] mob_web_dev

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);

(1) automatically GPS will turn on/off. - mob_web_dev
(1) 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); } } - mob_web_dev
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. - tony gil
(25) 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 not - alex
@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? - porg
(17) java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE - Abhi
It not work and show this error: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE - K.Sopheak
3
[+28] [2013-09-22 16:48:42] user529543

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) {}
}

(5) +1 for mentioning this method. It should work with a system-app on a nonrooted device as well. - AlexS
this is the right way. Works on every version of Android, no need any trick! - BQuadra
turning off gps is not working!! can you please tell me why and the possible solution. - Shivansh
now the gps is turning off and on perfectly but GPS is not working, i.e. giving location lat long 0.0 - Shivansh
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> only for the system aps - sijo jose
@user529543 where do i call this method? In splash? isn't there a way the gps will turn on automatically at the time of installing? - Pihu
Its just triggered animation Wifi Toogle, but actually not triggered Google Location Service. - Yohanim
4
[+26] [2017-03-02 13:21:34] The Black Horse

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


(1) this code is working fine but don't forgot location permission and playservice jar in gradle file ... - Akash pasupathi
5
[+23] [2014-08-04 19:35:33] Amaury Medeiros

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

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
[1] https://stackoverflow.com/questions/4721449/how-can-i-enable-or-disable-the-gps-programmatically-on-android/11503095#11503095

(2) So is it a comment or else what is the solution? - Shailendra Madda
@Shylendra Madda There is no solution for enabling GPS. You only can invoke the corresponding system dialog. - The incredible Jan
6
[+9] [2019-07-21 03:19:16] Mratyunjay Tripathi

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


7
[+6] [2013-02-13 09:26:47] OGP

To turn GPS on or off programatically you need 'root' access and BusyBox installed. Even with those, the task is not trivial.

Sample's here: Google Drive [1], Github [2], Sourceforge [3]

Tested with 2.3.5 and 4.1.2 Androids.

[1] https://docs.google.com/folderview?usp=sharing&id=0B7zaudXThbF8eTgwWlFFdE1VMWs&tid=0B7zaudXThbF8YU5VN2kxOE1XNkE
[2] https://github.com/sms2000/GPSToggler
[3] http://sourceforge.net/p/gpstoggler/code/ci/0accaacfbd13b22b2d5ae0a025722bcd2aba3c36/tree/

sample isn't available anymore. - android developer
Here is the latest: rapidshare.com/files/1458124346/GPSToggler-20130222.7z I erased the old version by accident. BusyBox is not required anymore. - OGP
still not available. maybe use a different file upload service? - android developer
I made the folder public and verified. Now it can be downloaded. Also my private FTP here: StackExchange:se@oldgopher.gotdns.com - OGP
looks very nice. as i can see "SystemMover","KernelServices" are responsible of converting the apk to a system app. what are the "GPSBroadcastReceiver","WatchdogThread" for ? do they poll the running tasks in order to automatically turn on/off the gps when google maps or waze are opened? why don't you put the project on sourceForge so that it keeps being published? - android developer
i think you should also have added an option to uninstall the app , and avoid putting the apk in the assets folder (instead use the current one, and move itself to there). this way you can also avoid other apps enabling the gps by using your app. - android developer
This app has little to do with GPS actually. It's a testbed for different technologies I learned like moving apps to /system/app, working with widgets, using native code with root and so on. I'm going to add uninstall feature sure but not to move the app itself to /system/app. The /system FS is so small usually I don't want to overload it. The latest version totally omits both STericsson system library and BusyBox. - OGP
I don't want to go to SystemForge, CodeGuru etc. I'm not good with writing articles. - OGP
The GIT repository has been created: git clone git://git.code.sf.net/p/gpstoggler/code gpstoggler-code - OGP
the website is not available. - android developer
Did you use GIT to download the solution? I verified it's OK. "git clone git://git.code.sf.net/p/gpstoggler/code gpstoggler-code" - OGP
i thought it's like on github , which allows to show more info , plus download directly from the website. - android developer
similar , but the link you've provided doesn't have a "download as zip file" feature. - android developer
nice. thanks mate. If you wish , you can post your answer here: stackoverflow.com/questions/11373234/… . if you also have a solution without converting the app to a system app (or somehow uninstall it upon uninstallation of the app that uses it) , i will also set it as the correct answer. - android developer
btw, you can listen to the uninstallation of the normal app inside the system app (and take a query about it upon boot,just in case) so that it would uninstall itself instead of the user needing to do so manually. - android developer
This is not trivial for a system application to uninstall itself. I know how to do it but the system application also has to ask for root privileges which is not good. Currently I'm more or less satisfied with the idea of 'uninstall' button. - OGP
Th code is not ready. Shortly I did the following: copied a small .so executable into /system/lib and when the system module recognized the GUI uninstalled it requested 'su', launched the .so module and immediately crashed itself through the kill process . The .so deleted .APK from /system/app. The only residue is that small .so left in /system/lib. The main problem is the system module requires 'root'. Theoretically it's possible to create an 'su' substitute which bypasses the SuperUser GUI and use it. Too many nails in ass... - OGP
can't you use something similar to "su adb uninstall" ? even if the user would see a dialog, it's better than leaving things behind... - android developer
Regardless of the method used You need a native module to delete the system APK. I'm investigating how to do automatic system module remove after uninstall finished. - OGP
The latest version supposedly uninstalls itself correctly. Small residue left. github.com/sms2000/GPSToggler - OGP
what do you mean? does it leave traces? of what kind? - android developer
It leaves a small module in /system/xbin. Currently I have no idea how to remove it automatically. When the GUI is removed with uninstaller the system APK removes itself with the help of the system module. The system module can bypass the SU and no dialog shown to the user. But who will remove the system module? Well, actually that also can be arranged... I have a couple of ideas. - OGP
Cool. couldn't the system app itself request to uninstall itself, using root permissions or something, instead of using scripts ? - android developer
You can 'open' internals of PackageManager and ApplicationManager and call hidden methods. Someone stated in StackExchange this allows to uninstall any APK. I tried to uninstall self but failed. Maybe I missed a bit. The next version of the GPSToggler should uninstall self correctly. - OGP
8
[+4] [2021-06-19 17:19:08] Peter Z.

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"/>


9
[+2] [2011-01-18 14:19:58] Damian KoĊ‚akowski

Maybe with reflection tricks around the class android.server.LocationManagerService [1].

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

[1] https://android.googlesource.com/platform/frameworks/base/+/master/services/java/com/android/server/LocationManagerService.java
[2] http://developer.android.com/reference/android/provider/Settings.Secure.html#setLocationProviderEnabled%28android.content.ContentResolver%2c%20java.lang.String%2c%20boolean%29

(3) 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 :) - maid450
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. - Flow
10
[+2] [2012-04-04 03:41:17] gobernador

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 [1]

This solution would require the WRITE_SETTINGS and WRITE_SECURE_SETTINGS permissions.

[1] https://stackoverflow.com/questions/4015094/android-enable-and-disable-gps#comment4306348_4015152

@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" - android developer
@android Read the last sentence of this post. Using this method will require the android.permission.WRITE_SECURE_SETTINGS permission in the Manifest. - gobernador
(1) i know . i've already added it . it tells me that even though it's already in the manifest. - android developer
so it's impossible even for rooted devices?! - android developer
@androiddeveloper you can convert your application into System app and try this..this snippet will work! - Ayush Goyal
11
[+2] [2016-11-29 07:49:59] AMAN SINGH

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);

What is mLocationPermissionGranted? - Bhavin Patel
that is for checking if the permission is granted or not for Location. this is run time permission granted. - AMAN SINGH
you can also go through by simply setting the value true, if you already granted the permission on pre-lollipop device - AMAN SINGH
12
[+2] [2016-12-30 13:19:01] DarwinFernandez

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

13
[+2] [2020-03-20 13:25:41] Marci

This one works for me.

It is a simpler solution than Rj0078's answer [1] 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
            }
        }
    }
[1] https://stackoverflow.com/a/42556648/11211963

14
[+1] [2016-01-14 21:49:02] Human

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


Thanks. But the Google Play Services 7 can be used with old android versions? (API 14 - 23) - JCarlosR
15
[+1] [2020-10-09 17:29:47] Javier Castellanos Cruz

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;
        }
    }
}

16
[0] [2018-10-05 18:34:09] sass

You just need to remove the LocationListener from LocationManager

manager.removeUpdates(listener);

17
[0] [2019-02-08 07:49:47] Gaurav Lambole

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);
} 

18