是否有可能在任何位置提供使能/禁止,并确定什么样的行动发生于收到通知?有可能、位置、行动、通知

2023-09-06 03:55:36 作者:許我三千筆墨畫你绝世倾城

我想,当用户启用或禁用任何网络或GPS位置收到通知,而且​​重要的是我想知道哪一个他们已经改变,以及如何。我有一个广播接收器的 android.location.PROVIDERS_CHANGED 广播的意图,这是接收正确的广播。

I wish to receive a notification when the user enables or disables either Network or GPS locations, and importantly I wish to know which one they have changed and how. I have a broadcast receiver for the android.location.PROVIDERS_CHANGED broadcast intent and this is receiving the correct broadcast.

我现在需要尝试,并确定已发生的动作即开启或关闭,哪些供应商已被更改。我知道,我可以保持每个供应商的状态,然后当我收到他们已经改变,那​​么我可以计算出发生了什么变化的通知,我在寻找这样做的更标准的方法。广播意图似乎不具有任何额外指示哪个提供商已经改变。

I now need to try and determine which action has occurred i.e. enable or disable and which provider has been changed. I know that I could keep the state of each provider and then when I receive notification that they have changed then I could work out what has changed, I am looking for a more "standard" method of doing this. The broadcast intent does not seem to have any extras to indicate which provider has changed.

这是在code我现在。

This is the code I have currently.

    public class LocationProviderChangedReceiver extends BroadcastReceiver {
    private final static String TAG = "LocationProviderChangedReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
      if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
      {
        Log.i(TAG,"Location Providers changed");
        Bundle bundle = intent.getExtras();
        if (bundle == null) {
          Log.d(TAG, "No extras data");
         } else {
           Log.d(TAG, "Bundle received of size " + bundle.size);
         } 
      }
    }
  }

这是从我的清单

And this is a small extract from my Manifest

  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

  <receiver 
    android:name=".LocationProviderChangedReceiver"
    android:exported="false">
    <intent-filter>
      <action android:name="android.location.PROVIDERS_CHANGED" />
      <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
  </receiver>

这将是完美的,如果有那说明该供应商发生了变化,是否被启用或禁用广播中的额外费用。不幸的是这不是这种情况。有没有人知道任何机制,通过它我可以决定什么状态,而维护我自己的状态变量发生了变化。

This would be perfect if there was an extra within the Broadcast that stated which provider had changed and whether it was enabled or disabled. Unfortunately this is not the case. Is anyone aware of any mechanism by which I can determine what state has changed without maintaining my own state variables.

在一个理想的世界我的变化不断地监测,但只监听位置的变化偶尔。我想,以避免不断地监测位置的变化。

In an ideal world I would monitor for changes constantly but only listen for location changes occasionally. I would like to avoid constantly monitoring for location changes.

推荐答案

我希望这不违背你的要求

I hope that this doesn't contradict your requirement

我知道,我可以保持每个供应商的状态,然后当我   收到,他们已经改变,那​​么如果我去通知什么   已经改变了,我找了一个这样做的更标准的方法。

I know that I could keep the state of each provider and then when I receive notification that they have changed then I could work out what has changed, I am looking for a more "standard" method of doing this.

...但我认为这样做的最好的,标准,最灵活的方式是让你的 LocationProviderChangedReceiver 实施的 LocationListener的 接口,然后实施 onProviderEnabled() onProviderDisabled()像这样:

...but I would think the best, "standard", and most flexible way of doing this is to let your LocationProviderChangedReceiver implement the LocationListener interface and then implement onProviderEnabled() and onProviderDisabled() like so:

public void onProviderEnabled(String provider) {
  if(provider.equals(LocationManager.GPS_PROVIDER)){
    ...
  } else if (provider.equals(LocationManager.NETWORK_PROVIDER)){
    ...
  }
}

请注意,您应该添加 ACCESS_FINE_LOCATION 允许您的清单,如果你还没有准备好。此外,其他提供者(超出网络和GPS)可以根据上下文,如 PASSIVE_PROVIDER 甚至 FUSED_PROVIDER

Note that you should add the ACCESS_FINE_LOCATION permission to your manifest if you haven't already. Also, other providers (beyond "Network" and "GPS") may apply depending on the context, like PASSIVE_PROVIDER or even FUSED_PROVIDER.

更新答案: 如果不断地监听位置的变化是你没有选择, LocationManager 也知道其中提供当前已启用:

Updated answer: If constantly listening for location changes is no option for you, the LocationManager also knows which provider is currently enabled:

LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

...这样你就可以与使用这些检查你一起的BroadcastReceiver 来避免手动持有任何启用/禁用标志。 除此之外,有一个称为意图 android.location.GPS_ENABLED_CHANGE ,你可以尝试接收(和处理)为好。但由于这种意图隐藏在正式文件,它可能不是安全使用它,正如这个答案。

...so that you could use these checks together with your BroadcastReceiver to avoid manually holding any enabled/disabled flags. Beyond that, there is an intent called android.location.GPS_ENABLED_CHANGE which you could try to receive (and process) as well. But since this intent is hidden in the official documentation, it might not be safe to use it, as mentioned in this answer.

均匀另一种方法: Android的默认设置切换小部件(你知道我的意思)通过订阅 android.location.PROVIDERS_CHANGED 意图(像你这样做)显示启用/禁用状态的GPS触发通过用户设置的GPS状态请求:

Even another approach: Android's default settings toggle widget (you know what I mean) displays the GPS enabled/disabled state by subscribing to the android.location.PROVIDERS_CHANGED intent (like you do) to trigger a request of the GPS state via the user settings:

@Override
public int getActualState(Context context) {
  ContentResolver resolver = context.getContentResolver();
  boolean on = Settings.Secure.isLocationProviderEnabled(
                 resolver, LocationManager.GPS_PROVIDER);
  return on ? STATE_ENABLED : STATE_DISABLED;
}

(从官方消息来源的)。 你能够适应这种方法对其他位置的供应商也是如此。

(from the official sources). You could adapt this approach for other location providers as well.