Organizational Research By

Surprising Reserch Topic

Question:Toggle gps on root devices on Android


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.

asked Sep 13, 2013 in ANDROID by anonymous
edited Sep 12, 2013
0 votes
68 views



Related Hot Questions

4 Answers

0 votes
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: - Enable GPS programatically like Tasker - a/10004614/238722

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

UPDATE

The answer linked related to BusyBox contains this working sample project available for download.
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013
0 votes
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

            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.

    

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.
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013
0 votes
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: - Enable GPS programatically like Tasker - a/10004614/238722

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

UPDATE

The answer linked related to BusyBox contains this working sample project available for download.
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013
0 votes
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

            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.

    

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.
answered Sep 13, 2013 by rajesh
edited Sep 12, 2013

...