Вы находитесь на странице: 1из 10

sign up

Stack Overflow

log in

Questions Tags Users Badges Unanswered Ask

Read this post in our app!

81

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


android

gps

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?

share

improve this question


maid450
4,930 1 24 30

Asked
Jan 18 '11 at 7:23

Shog9
105k 28 177 213

Edited
Jul 25 '14 at 22:01

10 Answers

122

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

Order By

Votes

here's some example code i use

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

share

improve this answer


Ben H
1,868 1 11 22

Answered
Mar 14 '11 at 23:26

Edited
Aug 4 '11 at 19:56

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 Jun 22 '11 at
16:47

As of this comment's writing, this exploit still works on a 2.2.1 Android phone. Nice find, Ben H. Qix Aug 17 '11 at 15:33

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 Nov 15 '12 at 22:30

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 Jan 2 '13 at 12:44

hahaha... this exploit reemerged in 4.2.2, Surprised to see it.. GOD! amithgc Apr 16 '13 at 11:57
show 15 more comments

41

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

share

improve this answer

Debugger
896 6 18

Answered
Jul 16 '12 at 11:14

automatically GPS will turn on/off. Debugger Jul 16 '12 at 11:19

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); } }
Debugger Jul 26 '12 at 11:27

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 Aug 6 '12 at 0:38

19

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 Aug 21 '12 at 7:20
This doesn't work on Sony Tipo non-rooted phone. :-( Sathesh Jan 28 '13 at 22:04
show 4 more comments

20

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 {

share

improve this answer


Answered
Sep 22 '13 at 16:48

user529543

Nate Zaugg
2,443 2 23 48

Edited
Sep 2 '15 at 15:03

+1 for mentioning this method. It should work with a system-app on a nonrooted device as well. AlexS Oct 24 '13 at 15:12
this is the right way. Works on every version of Android, no need any trick! BQuadra Jan 28 '14 at 16:38
works for me, after i set my app as system app...thanks :) TheOnlyJakobob Jun 16 '14 at 6:09
turning off gps is not working!! can you please tell me why and the possible solution. Shivansh Sep 5 '14 at 7:40
now the gps is turning off and on perfectly but GPS is not working, i.e. giving location lat long 0.0 Shivansh Sep 5 '14 at 8:47
show 1 more comment

14

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

share

improve this answer


Amaury Medeiros
1,112 2 9 28

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

These are the implmented methods:

Answered
Aug 4 '14 at 19:35

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

share

improve this answer


Akshat
695 2 18 52

Answered
Nov 5 '15 at 22:09

Now this answer should be the accepted one. Thanks a lot Akshat!! Gurpreet Mar 4 at 4:58
You are welcome buddy. :) :) Akshat Mar 11 at 8:15
Needs Google API client integration hence only a solution for specific use cases, not fit for a generic solution. Cik Apr 23 at 12:40
i tried this one its not working Dilroop Singh May 23 at 20:34
add a comment

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, Github, Sourceforge
Tested with 2.3.5 and 4.1.2 Androids.

share

improve this answer


OGP
481 2 6 20

Answered
Feb 13 '13 at 9:26

IanB
2,567 1 6 21

Edited
Sep 29 '14 at 7:40

sample isn't available anymore. android developer Feb 23 '13 at 23:10


Here is the latest: rapidshare.com/files/1458124346/GPSToggler-20130222.7z I erased the old version by accident. BusyBox is not required anymore. OGP Feb 24 '13 at 13:11
still not available. maybe use a different file upload service? android developer Feb 24 '13 at 18:16
I made the folder public and verified. Now it can be downloaded. Also my private FTP here: StackExchange:se@oldgopher.gotdns.com OGP Feb 25 '13 at 7:04
Another mirror: docs.google.com/folder/d/0B7zaudXThbF8YU5VN2kxOE1XNkE/ OGP Feb 25 '13 at 17:59
show 25 more comments

Using com.google.android.gms:play-services:8.1.0 or 7
This is the official Google Sample

share

improve this answer


Pragadees
121 1 4
Jyotman Singh
1,448 1 4 16

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

Answered
Oct 8 '15 at 11:05

Edited
Mar 15 at 6:58

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.

share

improve this answer


Community Wiki

gobernador
Answered
Apr 4 '12 at 3:41

but your phone must be root. milind Jul 11 '12 at 19:01

@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 Aug 4 '12 at 10:23

@android Read the last sentence of this post. Using this method will require the android.permission.WRITE_SECURE_SETTINGS permission in the Manifest. gobernador Aug 4
'12 at 15:18

i know . i've already added it . it tells me that even though it's already in the manifest. android developer Aug 4 '12 at 17:00

@android It looks like you're not the first one to have this problem gobernador Aug 5 '12 at 3:36
show 3 more comments

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


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

share

improve this answer

Damian Koakowski
2,425 13 22

Answered
Jan 18 '11 at 14:19

Gilles
53.1k 13 110 169

Edited
Jun 25 '12 at 17:10

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 Jan 18 '11 at 18:52

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

Feb 6 '14 at 11:19


add a comment

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

share

improve this answer


Hooman
1,441 1 9 12

Answered
Jan 14 at 21:49

meta chat tour help blog privacy policy legal contact us full site
Download the Stack Exchange Android app
2016 Stack Exchange, Inc

Вам также может понравиться