Toggle gps on root devices on Android

2019-01-15 20:30发布

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.

3条回答
ら.Afraid
2楼-- · 2019-01-15 20:35

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.

查看更多
该账号已被封号
3楼-- · 2019-01-15 20:38

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

查看更多
叼着烟拽天下
4楼-- · 2019-01-15 20:52

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.

查看更多
登录 后发表回答