Master_T
Master_T

Reputation: 7913

Android: detect when GPS is turned on/off (or when no app is using it anymore)

I'm on Android 2.3.7 and I'm trying to write a BroadcastReceiver that will get called when the user turns GPS on/off (ie: by tapping on the "use GPS satellites" in the options.

What I've done so far is this:

1) Created the following broadcastReceiver:

public class GPSStatusBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context arg0, Intent arg1) {
        Toast.makeText(arg0, "Broadcast received!", Toast.LENGTH_SHORT).show();

    }
}

2)Added this to the android manifest, inside the tags:

<receiver android:name=".GPSStatusBroadcastReceiver"> 
    <intent-filter> 
        <action android:name="android.location.PROVIDERS_CHANGED" /> 
    </intent-filter> 
</receiver>

Now the problem with this is that it appears not to be reliable. When I turn GPS on/ff the onReceive() method only runs sometimes (I'd say 1 time out 3) the other times it doesn't get called.

I want to know if there is a reliable way to detect when the GPS is turned off/on.

If there isn't it would be nice to be notified at least when no app is using the GPS anymoer (ie: when the gps icon disappears from statusbar, indicating no one is actively locating).

EDIT: Clarification: I don't want to do this while my app is running. I just whatn my app to be started when gps is turned on/off, do its thing and then terminate, I don't want to subscribe to LocationsUpdates...

Upvotes: 17

Views: 13686

Answers (4)

ARLabs
ARLabs

Reputation: 1524

Starting from API 19 you can listen for the intent action LocationManager.MODE_CHANGED_ACTION.

You can also get the current location mode as follows:

try
{
    int locationMode = android.provider.Settings.Secure.getInt(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE);
} catch (android.provider.Settings.SettingNotFoundException e)
{
    e.printStackTrace();
}

The value returned should be one of these:

android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING
android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
android.provider.Settings.Secure.LOCATION_MODE_OFF
android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY

Upvotes: 2

theWook
theWook

Reputation: 843

On API level 9 and higher you can use LocationManager.PROVIDERS_CHANGED_ACTION:

Broadcast intent action when the configured location providers change. For use with isProviderEnabled(String). If you're interacting with the LOCATION_MODE API, use MODE_CHANGED_ACTION instead.

Constant Value: "android.location.PROVIDERS_CHANGED"

Source

Upvotes: 9

stinepike
stinepike

Reputation: 54672

The following solution might be a weird solution but you can try it if you don't find any solution. Another problem with your solution is it works only after api level 9.

in a thread or service you can check the gps status periodically with a very short interval by using

 LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE );
 boolean statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);

it will use the permission

android.permission.ACCESS_FINE_LOCATION

Even though I am answering this, to me it should not be a good solution. Also there is a chance of minimum period interval delay. Just an option.

Upvotes: 4

poitroae
poitroae

Reputation: 21367

Use a LocationListener and override OnStatusChanged.

You can attach your listener using the requestLocationUpdates(String, long, float, LocationListener) method on your LocationManager instance.

Upvotes: -3

Related Questions