Search code examples
androidkotlinobservableandroid-broadcastreceiver

Broadcast receiver onReceive fires twice on location change


I want to know whenever user turn his gps off. I want to get informed about that action in different activities. I made Broadcast Receiver to listen for GPS state change. But almost always when i turn off GPS, my updateValue function get fired twice. How to get notified one time, when user turn his gps off? What i did wrong? Below is my code.

class GpsStatusReceiver : BroadcastReceiver() {
var observableGpsState: ObservableGpsState? = null

override fun onReceive(context: Context?, intent: Intent?) {
    val locationManager = context?.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        //GPS Turned on,OK..
    } else {
        if (observableGpsState == null)
            observableGpsState = ObservableGpsState.getInstance()
        observableGpsState?.updateValue(GPS_STATUS_TURNED_OFF)
    }
}

companion object {
    val GPS_STATUS_TURNED_OFF = "GPS_TURNED_OFF"
}}

My Observable

class ObservableGpsState: Observable(){

fun updateValue(data: Any) {
    synchronized(this) {
        setChanged()
        notifyObservers(data)
    }
}
companion object {
    private val instance = ObservableGpsState()
    fun getInstance(): ObservableGpsState {
        return instance
    }
}}

And (what I guess) is important from my Activity:

protected lateinit var observer: Observable

private fun registerGpsObserver(){
    observer = ObservableGpsState.getInstance()
    observer.addObserver(this)
}
private fun unregisterGpsObserver(){
    observer.deleteObserver(this)
}

override fun update(o: Observable?, arg: Any?) {
    MyApplication.get(baseContext).enableGpsDialog(this)
}

Solution

  • I would assume that this issue arises only on some devices (though I am not 100% sure about it, but it is the case when listening to network changes via a BroadcastReceiver so it would make sense).

    Anyway the simplest solution would be to Make an enum which holds the current State of your GPS. Only if the State changes notify the Observer. This way the onReceive could be called 1000 times but your Observer gets notified only once.