Android 广播接收器onReceive在位置更改时触发两次
我想知道用户何时关闭gps。我想在不同的活动中了解这一行动。我制作了广播接收器来监听GPS状态的变化。但几乎每次我关闭GPS时,我的updateValue函数都会被触发两次。当用户关闭gps时,如何获得一次通知?我做错了什么?下面是我的代码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
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)
我如何才能做到这一点?