How can I enable or disable the GPS programmatical

2018-12-31 01:42发布

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?

标签: android gps
13条回答
人气声优
2楼-- · 2018-12-31 02:10

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);
查看更多
无与为乐者.
3楼-- · 2018-12-31 02:12

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
查看更多
与君花间醉酒
4楼-- · 2018-12-31 02:15

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

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

查看更多
呛了眼睛熬了心
5楼-- · 2018-12-31 02:17

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

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
}
查看更多
余欢
6楼-- · 2018-12-31 02:18

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.

查看更多
无色无味的生活
7楼-- · 2018-12-31 02:19

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) {}
}
查看更多
登录 后发表回答