39

I would like to detect when the user changes the GPS settings on or off for an Android phone. Meaning when user switches GPS sattelite on/off or detection via access points etc.

Drejc
  • 14,196
  • 16
  • 71
  • 106

4 Answers4

43

As I have found out the best way to do this is to attach to the

<action android:name="android.location.PROVIDERS_CHANGED" />

intent.

For instance:

<receiver android:name=".gps.GpsLocationReceiver">
        <intent-filter>
            <action android:name="android.location.PROVIDERS_CHANGED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

And then in the code:

public class GpsLocationReceiver extends BroadcastReceiver implements LocationListener 
...

@Override
public void onReceive(Context context, Intent intent)
{
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
        { 
            // react on GPS provider change action 
        }
}
Drejc
  • 14,196
  • 16
  • 71
  • 106
  • Works not only for GPS but also for network location services. – stevo.mit Sep 08 '14 at 13:29
  • Upvoted, but why do you need ``? – zelanix Jun 19 '15 at 09:53
  • 4 years ago it was needed, I think ... who would know. Try it without if it works so much better. – Drejc Jun 19 '15 at 17:29
  • for what purpose you are using `.matches()` method instead of `equals()/equalsIgnoreCase()`??? – khaleel_jageer Oct 30 '15 at 07:08
  • Probably it was copy pasted from some working code where .matches() was appropriate. In this case .equals() is better. But both will work. Hey it's 4+ years since then ... who would now. – Drejc Oct 31 '15 at 08:15
  • 3
    you don't need implements LocationListener – Radesh Oct 02 '18 at 13:34
  • 2
    @Radesh this question is 7 years old ... in 2011 you had to – Drejc Oct 03 '18 at 06:31
  • For API level 26 and above, this solution doesn't work due to restrictions in implicit broadcast. It fails with "BroadcastQueue: Background execution not allowed: receiving Intent { act=android.location.PROVIDERS_CHANGED } " Read More at: https://developer.android.com/guide/components/broadcast-exceptions and https://developer.android.com/about/versions/oreo/background – Dr. DS Apr 17 '20 at 06:53
21

Here is a code sample for a BroadcastReceiver detecting GPS location ON/OFF events:

private BroadcastReceiver locationSwitchStateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

            if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.getAction())) {

                LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (isGpsEnabled || isNetworkEnabled) {
                    //location is enabled
                } else {
                    //location is disabled
                }
            }
        }
    };

Instead of changing your manifest file, you can register your BroadcastReceiver dynamically:

IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
mActivity.registerReceiver(locationSwitchStateReceiver, filter);

Don't forget to unregister the receiver in your onPause() method:

mActivity.unregisterReceiver(locationSwitchStateReceiver);
matdev
  • 4,115
  • 6
  • 35
  • 56
4

Try this,

try {
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

            Log.i("About GPS", "GPS is Enabled in your devide");
        } else {
            //showAlert
        }
Andro Selva
  • 53,910
  • 52
  • 193
  • 240
  • 9
    I know how to detect if a provider is on or off. But I would like to detect the change, when the user switches a provider on or off in a setting dialog. – Drejc Jun 16 '11 at 07:21
3

Impement android.location.LocationListener, there you have two functions

public void onProviderEnabled(String provider);
public void onProviderDisabled(String provider);

Using this you can find out when the requested provider is turned on or off

Azlam
  • 2,052
  • 3
  • 24
  • 28
  • This should be the accepted answer. The accepted answer is already using LocationListener, so why not use the given methods for the task. – VipulKumar Dec 24 '14 at 14:12
  • 10
    You can detect on/off state but you can't detect the change (switch) – Drejc Jan 26 '15 at 10:16