Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.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 是否可以在启用/禁用任何位置提供程序时获取通知,并确定发生了什么操作?_Android_Android Location - Fatal编程技术网

Android 是否可以在启用/禁用任何位置提供程序时获取通知,并确定发生了什么操作?

Android 是否可以在启用/禁用任何位置提供程序时获取通知,并确定发生了什么操作?,android,android-location,Android,Android Location,我希望在用户启用或禁用网络或GPS位置时收到通知,重要的是,我希望知道他们更改了哪个位置以及如何更改。我有一个android.location.PROVIDERS的广播接收器,它改变了的广播意图,正在接收正确的广播 我现在需要尝试并确定发生了哪些操作,即启用或禁用,以及更改了哪些提供程序。我知道我可以保留每个提供者的状态,然后当我收到通知说他们已经更改时,我就可以找出发生了什么更改,我正在寻找一种更“标准”的方法来做到这一点。广播意图似乎没有任何额外内容来表明哪个提供商已更改 这是我目前拥有的代

我希望在用户启用或禁用网络或GPS位置时收到通知,重要的是,我希望知道他们更改了哪个位置以及如何更改。我有一个android.location.PROVIDERS的广播接收器,它改变了的广播意图,正在接收正确的广播

我现在需要尝试并确定发生了哪些操作,即启用或禁用,以及更改了哪些提供程序。我知道我可以保留每个提供者的状态,然后当我收到通知说他们已经更改时,我就可以找出发生了什么更改,我正在寻找一种更“标准”的方法来做到这一点。广播意图似乎没有任何额外内容来表明哪个提供商已更改

这是我目前拥有的代码

    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);
         } 
      }
    }
  }
这是我清单上的一个小摘录

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

如果在广播中有一个额外的内容,说明哪个提供商已经更改,以及它是启用还是禁用的,这将是完美的。不幸的是,情况并非如此。有没有人知道有什么机制可以让我在不维护自己的状态变量的情况下确定状态发生了变化


在一个理想的世界里,我会不断地监测变化,但只是偶尔听一下位置的变化。我希望避免不断监视位置变化。

我希望这不会与您的要求相矛盾

我知道我可以保留每个提供者的状态,然后 收到他们已更改的通知,然后我可以确定是什么 已经改变,我正在寻找一个更“标准”的方法来做这件事

…但我认为最好的“标准”和最灵活的方法是让您的
LocationProviderChangedReceiver
实现接口,然后实现
onProviderEnabled()
onProviderDisabled()
如下:

public void onProviderEnabled(String provider) {
  if(provider.equals(LocationManager.GPS_PROVIDER)){
    ...
  } else if (provider.equals(LocationManager.NETWORK_PROVIDER)){
    ...
  }
}
请注意,如果您尚未将
ACCESS\u FINE\u LOCATION
权限添加到您的清单中,则应将其添加到清单中。此外,其他提供商(除“网络”和“GPS”之外)可能会根据上下文应用,例如,甚至

更新答案:
如果您没有选择经常收听位置变化,则客户也知道:

…以便您可以将这些检查与
BroadcastReceiver
一起使用,以避免手动保留任何启用/禁用标志。 除此之外,您还可以尝试接收(和处理)一个名为intent的意图。但是,由于官方文档中隐藏了这一意图,因此使用它可能不安全,如中所述

甚至还有另一种方法:
Android的默认设置切换小部件(你知道我的意思)通过订阅
Android.location.PROVIDERS\u更改
intent(像你一样)以通过用户设置触发GPS状态请求来显示GPS启用/禁用状态:

@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;
}
(来自网络)。

您也可以将此方法应用于其他位置提供程序。

在接收器上,您只需检查哪些提供程序已启用:

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE)
List<String> providers = lm.getProviders(true);
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION\u服务)
列表提供程序=lm.getProviders(true);
通过这种方式,您可以获得所有启用提供程序。

这对我很有用:

将接收者添加到清单文件:

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

尽管由于明显的原因多次调用此接收器,但这将告诉您状态。

由于@usman的回答,我们可以应用解决方案,而无需
通过以下方式扩展类

AndroidManifest.xml

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

很抱歉在您回答问题后更改了问题和要求,但我正在寻找一种不用监听位置的方法来监视此问题。我确实在不同的时间点请求位置更新,但我希望不断监视提供者的更改,而不必不断侦听位置。好的,在这种情况下,
LocationManager
也可以提供帮助。我更新了我的答案。
public class LocationProviderChangedReceiver  extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {

        boolean anyLocationProv = false;
        LocationManager locationManager = (LocationManager) MyMainActivity.context.getSystemService(Context.LOCATION_SERVICE);

        anyLocationProv |= locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        anyLocationProv |=  locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        Log.i("", "Location service status" + anyLocationProv);


    }

}
<receiver android:name="com.eegeo.location.LocationProviderChangedReceiver">
    <intent-filter>
        <action android:name="android.location.PROVIDERS_CHANGED" />
    </intent-filter>
</receiver>
public class LocationProviderChangedReceiver {

    private mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String ability = (isGPSProviderEnabled() && isNetworkProviderEnabled()) ? "CAN" : "CANNOT";
            Log.d("", "The location " + ability + " be caught in high accuracy!");
        }
    };


    public startProviderChangeObserving () {
        registerReceiver(mReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));

    }


    public stopProviderChangeObserving () {
        unregisterReceiver(mReceiver);
    }   


    /**
    * Method to verify that the location providers wheter on or not on the device
    **/
    public boolean isGPSProviderEnabled() {
        return (Boolean) mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    public boolean isNetworkProviderEnabled() {
        return (Boolean) mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }

}