android 在设置中监听位置访问禁用/启用

erhoui1w  于 2023-04-18  发布在  Android
关注(0)|答案(4)|浏览(197)

在Android操作系统中,在“设置”--〉“位置服务”中,有一个名为“访问我的位置”的切换按钮,可用于禁用和启用应用程序的位置信息访问。
目前,我正在开发一个位置服务应用程序。我想知道,我如何在我的Android项目中收听此设置?是否有任何广播接收器可以让我立即知道用户何时禁用或启用“访问我的位置”?
如果没有任何广播接收器,我如何在我的Android项目中收听此更改?

yeotifhr

yeotifhr1#

这对我很有效:
将接收方添加到清单文件:

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

检查接收器中的两个位置提供程序:

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

    }

}

虽然由于明显的原因,这个接收器被调用了不止一次,但它会告诉你状态。

cx6n0qe3

cx6n0qe32#

你可以用这种方法简单得多。在BroadcastReceiver的**onReceive()**方法中:

ContentResolver contentResolver = getContext().getContentResolver();
    // Find out what the settings say about which providers are enabled
    int mode = Settings.Secure.getInt(
            contentResolver, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);

    if (mode == Settings.Secure.LOCATION_MODE_OFF) {
        // Location is turned OFF!
    } else {
        // Location is turned ON!
    }

感谢这段代码:LocationManagerTest.java

ngynwnxp

ngynwnxp3#

您可以使用下面的代码来检查位置服务是否启用

LocationManager lm = null;
 boolean gps_enabled,network_enabled;
    if(lm==null)
        lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    try{
    gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }catch(Exception ex){}
    try{
    network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }catch(Exception ex){}

   if(!gps_enabled && !network_enabled){
        dialog = new AlertDialog.Builder(context);
        dialog.setMessage(context.getResources().getString(R.string.gps_network_not_enabled));
        dialog.setPositiveButton(context.getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub
                Intent myIntent = new Intent( Settings.ACTION_SECURITY_SETTINGS );
                context.startActivity(myIntent);
                //get gps
            }
        });
        dialog.setNegativeButton(context.getString(R.string.Cancel), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub

            }
        });
        dialog.show();

    }
cgyqldqp

cgyqldqp4#

2023:当用户在窗帘菜单中切换位置时,这个解决方案会监听并做出React。困难的部分是弄清楚要使用哪个“意图”过滤器标志(LocationManager.PROVIDERS_CHANGED_ACTION)。
在我的示例中,我使用@Inject constructor(Hilt)。如果你不这样做,那么只需将context作为参数发送给register()unregister()register(context: Context)
Context上的扩展:

fun Context.isLocationEnabled(): Boolean {
  val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
  return LocationManagerCompat.isLocationEnabled(locationManager)
}

创建BroadcastReceiver:

class LocationBroadcastReceiver @Inject constructor(private val context: Context) : BroadcastReceiver() {

  private val locationStateChange: BehaviorRelay<Boolean> = BehaviorRelay.createDefault(context.isLocationEnabled())

  override fun onReceive(context: Context, intent: Intent) {
    val action = intent.action

    if (action == LocationManager.PROVIDERS_CHANGED_ACTION) {
      val state = context.isLocationEnabled()
      locationStateChange.accept(state)
    }
  }

  fun subscribeState(): Flowable<Boolean> {
    return locationStateChange.toFlowable(BackpressureStrategy.LATEST)
  }

  /**
  * Listen to subscribeState() to receive updates
  */
  fun register() {
    val filter = IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION)
    val receiverFlags = ContextCompat.RECEIVER_NOT_EXPORTED
    ContextCompat.registerReceiver(context, this, filter, receiverFlags)
  }

  fun unregister() {
    context.unregisterReceiver(this)
  }

}

现在您可以订阅

subscribeState()

从viewModel或compose类中调用并执行必须执行的操作。

相关问题