Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 广播接收器onReceive在位置更改时触发两次_Android_Kotlin_Observable_Android Broadcastreceiver - Fatal编程技术网

Android 广播接收器onReceive在位置更改时触发两次

Android 广播接收器onReceive在位置更改时触发两次,android,kotlin,observable,android-broadcastreceiver,Android,Kotlin,Observable,Android Broadcastreceiver,我想知道用户何时关闭gps。我想在不同的活动中了解这一行动。我制作了广播接收器来监听GPS状态的变化。但几乎每次我关闭GPS时,我的updateValue函数都会被触发两次。当用户关闭gps时,如何获得一次通知?我做错了什么?下面是我的代码 class GpsStatusReceiver : BroadcastReceiver() { var observableGpsState: ObservableGpsState? = null override fun onReceive(contex

我想知道用户何时关闭gps。我想在不同的活动中了解这一行动。我制作了广播接收器来监听GPS状态的变化。但几乎每次我关闭GPS时,我的updateValue函数都会被触发两次。当用户关闭gps时,如何获得一次通知?我做错了什么?下面是我的代码

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"
}}
我的可观察

class ObservableGpsState: Observable(){

fun updateValue(data: Any) {
    synchronized(this) {
        setChanged()
        notifyObservers(data)
    }
}
companion object {
    private val instance = ObservableGpsState()
    fun getInstance(): ObservableGpsState {
        return instance
    }
}}
(我猜)我的活动很重要:

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)
}

我假设这个问题只出现在某些设备上(虽然我不是100%确定,但通过
BroadcastReceiver
收听网络变化时会出现这种情况,所以这是有意义的)

无论如何,最简单的解决方案是创建一个
enum
,它保存您的
GPS
的当前
状态。仅当状态更改时通知观察者。通过这种方式,
onReceive
可以被调用1000次,但是您的
观察者只会收到一次通知。

我通过以下方法解决了问题:

 BroadcastReceiver gpsSwitchStateReceiver = new BroadcastReceiver() {
    //here you can check your current state when instanciate it.
        boolean oldLocationEnabled = isLocationSystemEnabled();

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                String action;
                if (intent != null && (action = intent.getAction()) != null && action.matches(LocationManager.PROVIDERS_CHANGED_ACTION)) {
                    boolean locationEnabled = isLocationSystemEnabled();
//this validation ensures that it is executed only once (since the receiver is executed in the UIThread) 
                    if (oldLocationEnabled != locationEnabled) {
                        if (locationEnabled) {
                        //your code here 
                        } else {
                        //when dont have location here
                        }
                    }
                    oldLocationEnabled = locationEnabled;
                }
            } catch (Exception ignored) {}
        }
    };

public boolean isLocationSystemEnabled() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        LocationManager locationManager = (LocationManager) ApplicationLoader.appContext.getSystemService(Context.LOCATION_SERVICE);
        boolean         isGPSEnabled    = false;
        boolean         isNetEnabled    = false;
        if (locationManager != null) {
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        }
        return isGPSEnabled || isNetEnabled;
    } else {
        String allowedLocationProviders = Settings.System.getString(ApplicationLoader.appContext.getContentResolver(), Settings.System.LOCATION_PROVIDERS_ALLOWED);
        if (allowedLocationProviders == null) {
            allowedLocationProviders = "";
        }
        return allowedLocationProviders.contains(LocationManager.GPS_PROVIDER);
    }
}

Android中有多个位置提供者。因此,您正在侦听的事件对应于提供程序更改,而不是位置激活。看

改用
LocationManager.MODE\u CHANGED\u ACTION
并使用
LocationManager.EXTRA\u location\u ENABLED
直接从
Intent
参数检索当前位置激活状态。例如:

val locationListener=object:BroadcastReceiver(){
覆盖接收(上下文:上下文?,意图:意图){
何时(val action=intent.action){
LocationManager.MODE\u已更改\u操作->{
val locationState=intent.getBooleanExtra(
LocationManager.EXTRA\u位置\u已启用,
假的
)
//使用locationState变量执行某些操作
}其他->{
Log.d(标记“不支持的操作收到$action”)
}
}
}
}
val intentFilter=intentFilter(LocationManager.MODE\u CHANGED\u操作)
registerReceiver(locationListener、intentFilter)
最后,当不再需要接收器时,不要忘记注销它。例如:

context.unregisterReceiver(locationListener)

我如何才能做到这一点?