5

Starting with some Android version (I think 2.3.x), you cannot turn on/off the GPS via the API, no matter what permissions the app has. In the past, it was possible by exploiting a bug in the power control widget (see here ), but now it's fixed.

Suppose I have a root access, how can I turn GPS on and off?


EDIT: this is how you get a permission to read logs on jelly bean , which is not allowed for normal apps anymore . I've tried to use a similar solution for the WRITE_SECURE_SETTINGS permission in order to toggle the gps , but it didn't work.


EDIT: so far , i've found only one solution that worked : converting the app to be a system app (a working solution can be found here , works even on android 4.2.1 ) . However, what i've thought of is using the root to bypass it from the beginning, as root permission can do everything according to what i know.

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • nope. wonder how come i'm the only one who asked it . – android developer Dec 31 '12 at 07:55
  • @androiddeveloper How comfortable are you with making another (really limited) apk and installing that to `system/app`? That should grant the apk any permissions needed. This is what avast does for its antitheft. One problem though, is uninstalling. – A--C Feb 23 '13 at 23:28
  • @androiddeveloper: Regarding "as root permission can do everything according to what i know.". That's not completely true. Android permissions are separete from linux permission. They have some overlap (as example some uid's mapped to some Android permissions), but generally you can treat them as two separate permissions layers. And as result, just having Linux permissions doesn't too much for android permissions (since they are application level entity about which Linux has no idea). – Victor Ronin Feb 26 '13 at 16:34
  • @A--C i know of this solution as written here : http://stackoverflow.com/a/14850224/878126 . problem is that i want to overcome the disadvantages of this method (like uninstallation). – android developer Feb 27 '13 at 18:58
  • @Victor Ronin are you sure about this? i thought that root permission is "the mother of all permissions" , which allows full control of everything. it can even replace the rom , as far as i know (though it's usually done via the bootloader. – android developer Feb 27 '13 at 19:00
  • @android developer: "the mother of all permissions". Yes and No. You are right, root is very powerful permission which allows you to do anything on device (on the very low level) - you can read/write to any file, you can access hardware, kill processes and so on. However, all of these are work with low level primitive. And let say you have spreadsheet application running on your Linux box. And because of some internal spreadsheet permissions spreadsheet application allows you to modify only first page and not second and third page. (I broke down to several comments, since it doesn't fit) – Victor Ronin Feb 27 '13 at 19:16
  • @androiddeveloper: So, the question is. Do you have any Linux API which will allow you to modify second and third page of spreadsheet (even if you have a root)?The answer is no.Linux permissions are only applicable to low level things (sockets, files, processes, threads) and they have no idea about anything high level. The same is true for Android. Android permissions are permissions implemented as part of Android OS, running in Java virtual machine running on top of Linux. It's too high level.So, as result, you can do whatever you want on low level, but you can't control high level that well. – Victor Ronin Feb 27 '13 at 19:20
  • @androiddeveloper: BTW. Feel free to contract me outside of SO (my email is in my profile) – Victor Ronin Feb 27 '13 at 19:21
  • @Victor Ronin but since android is open source , wouldn't it be possible for an app with root permission to override the permissions and force the permissions manager (or whatever that is responsible for granting permissions) to grant us the needed permission? – android developer Feb 27 '13 at 20:10
  • @androiddeveloper: To do this, you need either to modify Android OS code, recompile it and upload to your device (which won't fly for the end user) or you need to find some flaw in the Android logic and use it. Both methods which we discussed falls under the category of flaw in the logic. You are trying to find some way to grant high level permission through usage of root omnipotence on the low level (as example, ability to mount system partition for write or ability to change uid at runtime). – Victor Ronin Feb 27 '13 at 20:29
  • @VictorRonin you mean to tell me that there is no app (like the security anti-theft apps out there) that could toggle the gps ? – android developer Feb 27 '13 at 22:31
  • @androiddeveloper: Hm.. Strange. I believe I left the comment, but it wasn't shown. I meant to say that having Linux root permission gives omnipotence on the low level, but doesn't grant any higher level permissions directly. So, as result you have to search for some tricks to get them (as you are doing right now). – Victor Ronin Feb 27 '13 at 23:19

3 Answers3

3

I looked a little bit in Android source code and found following code

 public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
            String allowedProviders = Settings.Secure.getString(cr, LOCATION_PROVIDERS_ALLOWED);
            return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
        }

  /**
   * Thread-safe method for enabling or disabling a single location provider.
   * @param cr the content resolver to use
   * @param provider the location provider to enable or disable
   * @param enabled true if the provider should be enabled
   */
        public static final void setLocationProviderEnabled(ContentResolver cr,
                String provider, boolean enabled) {
            // to ensure thread safety, we write the provider name with a '+' or '-'
            // and let the SettingsProvider handle it rather than reading and modifying
            // the list of enabled providers.
            if (enabled) {
                provider = "+" + provider;
            } else {
                provider = "-" + provider;
            }
            putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
        }       

I believe, if you have root access then you can both read and write Settings.Secure. this way you should be able to control GPS (setLocationProviderEnabled).

However, as I understand it won't turn off a GPS hardware, just will ignore this location provider.

I am not aware of interfaces which will talk to GPS and turn off hardware. However, another option which you have is to disable kernel module responsible for GPS (I am not aware of it's name).

Update 1

I checked how WRITE_SECURE_SETTIONS is defined in Android (4.1). Here it is

   <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
        android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
        android:protectionLevel="signature|system|development"
        android:label="@string/permlab_writeSecureSettings"
        android:description="@string/permdesc_writeSecureSettings" />

Based on "system" level. Add it to the manifest of your application, copy this application to the system image (you will need to mount it as writable) and you should be good to go.

And one more thing. uid shell has this permission.

 <assign-permission name="android.permission.WRITE_SECURE_SETTINGS" uid="shell" />   

I don't remember exactly, but there is some way to temporary change uid (if you are root). I was it somewhere in Android code. So, you can change uid to shell, do something and change it back.

Update 2

I found this method of chaing uid.

If you download AOSP, you can find how it used in native library in coulpe of places

./base/cmds/screenshot/screenshot.c

It does setuid(AID_SHELL);

./native/cmds/dumpstate/dumpstate.c

setuid(AID_SHELL)

and it in couple of other places.

I think you should experiment with it to get AID_SHELL group which has WRITE_SECURE_SETTINGS permission.

Update 3

I am not sure about the details. I believe there should a native driver and unix device for gps hardware. However, it could be named differently on different devices.

You can try to use rmmod linux command to remove some module. I believe it should disable gps.

Victor Ronin
  • 22,758
  • 18
  • 92
  • 184
  • the problem is , i can't get the WRITE_SECURE_SETTINGS permission even on a rooted device. what i'm trying is : "su -c pm grant android.permission.WRITE_SECURE_SETTINGS" . it worked fine for getting the permission to read logs , but now it doesn't work for this permission. some apps claim to succeed achieving this . wonder how they work. – android developer Feb 23 '13 at 23:18
  • @androiddeveloper: I think it make sense to include this piece of info into the question. I will take a look what's going on with WRITE_SECURE_SETTINGS – Victor Ronin Feb 23 '13 at 23:21
  • updated question to link to the logs permission getting on rooted devices. as i've mentioned , the same approach didn't work in this case. not only that, but i think that the new 4.2 version doesn't allow toggling the mobile data (found it out today as widgetsoid app wasn't able to toggle it). – android developer Feb 23 '13 at 23:27
  • so there is nothing i can do to avoid telling the (power) user to install the app as a system app? nothing to bypass this restriction, even with root permissions that should be able to do everything? i think that as a system app, you don't need to put extra flags in the manifest for this permission. however , i never found a way to automatically convert an app into a system app (within the same app) . – android developer Feb 24 '13 at 07:00
  • do you think you can find a lead of how to do it? – android developer Feb 24 '13 at 23:12
  • What do you mean "a lead of how to do it"? I think, the best idea would be for your to look at these two files which I mentioned to see how it is used there. And you will need to create a native library and have this code in there and call it from Java code. – Victor Ronin Feb 24 '13 at 23:37
  • please forgive me for sounding a bit rude , and i really appreciate that you've found some clues , but i want to know if it's possible and how to do it using root permissions. i am not so familiar with the understanding of the android OS source code – android developer Feb 24 '13 at 23:57
  • @androiddeveloper: no problem at all. you are not rude. I just wasn't sure what you are missing. Now I understand, that the problem is lack of experience with android source code. I will try to come up with some sample code. – Victor Ronin Feb 25 '13 at 00:10
  • @androiddeveloper: Unfortunately, I won't be able to make a sample for you. I touched NDK almost a year ago and I figured out that it could take me half a day (in good case) to build a sample. I am sorry, I just don't have enough time for this right now. – Victor Ronin Feb 25 '13 at 17:02
  • actually google has made it easier to build using NDK. you simply have to right click on the project and choose "android tools->add native support" . everything is automatic from there. even building. the only thing i miss is debugging, which is too many steps for making it work on windows. – android developer Feb 25 '13 at 20:06
  • I appreciate your effort , but I will only grant the bounty for a working solution or an answer that fits the most. – android developer Feb 28 '13 at 15:04
2

NO Need system app just use su for enabling gps on high accuracy mode just use

 Process proc=Runtime.getRuntime().exec(new String[]{"su",
"pm grant com.your_app_packagename android.permission.WRITE_SECURE_SETTINGS",
"settings put secure location_providers_allowed gps,network,wifi"});
 proc.waitFor();

Run these command on background thread :)

further you can refer to this link here

Dayvon
  • 87
  • 2
  • 11
  • Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Feb 10 '16 at 16:26
  • These are the commands need to run in background thread. First command for call su, second for granting secure permission third for turning on gps with high accuracy – Dayvon Feb 12 '16 at 08:07
1

This SO Question seems to be the closest to anything related on the topic.

There was a bug exploit up until version 2.2 which enabled changing the GPS setting. After 2.3, it seems as if it's currently impossible to do without user intervention.

Here are the answers/comments of several unsuccessful attempts: - How can I enable or disable the GPS programmatically on Android? - https://stackoverflow.com/a/10004614/238722

Apparently there is a way of doing it with BusyBox, but I can't find anything solid online. Source: https://stackoverflow.com/a/14850224/238722

UPDATE

The answer linked related to BusyBox contains this working sample project available for download.

Community
  • 1
  • 1
Jesse
  • 8,605
  • 7
  • 47
  • 57
  • 1
    even on a rooted device , you can't just aquire the permission as used for other permissions? you have to put the app as a system app? – android developer Feb 23 '13 at 23:14
  • That's what I gathered from the posts and quick online research, yup. Apparently the Android OS only permits system apps to make that change. – Jesse Feb 23 '13 at 23:21
  • can you please try to find a busyBox solution for this? – android developer Feb 28 '13 at 15:03
  • @androiddeveloper The answer related to BusyBox has a working [sample project](http://rapidshare.com/files/1458124346/GPSToggler-20130222.7z) available for download. I don't have an Android device with me, therefore I can't test it; the poster confirms that it works on 4.1.2, though. – Jesse Feb 28 '13 at 18:14
  • Some ROMs actually allow to use Security not from system applications only. Also there is no necessity to ask the EndUser to install a module into /system/app, you can do it in background. But you still need the root access and have to reboot the phone after. To have a sort of generic solution you do need a) root, b) system APK and c) reboot. – OGP Mar 01 '13 at 12:15