Android 如何检测用户何时打开/关闭GPS状态?

Android 如何检测用户何时打开/关闭GPS状态?,android,gps,broadcastreceiver,Android,Gps,Broadcastreceiver,我想阻止用户更改我的应用程序中的WiFi、GPS和加载设置。运行我的应用程序时,用户无需打开/关闭WiFi和GPS。(从通知栏)。是否存在用于收听GPS开/关的广播接收器?这是不可能的。你不能随心所欲地控制/限制硬件的状态。这将是危险的,因为API中没有这样的API,所以不存在这样的API。您可以注册一个广播接收器,用于收听意图操作提供者\u更改\u操作。这将在配置的位置提供程序更改时广播。你可以参考这个 您可以通过以下方式检测GPS的状态 看。向locationManager.addGpsSt

我想阻止用户更改我的应用程序中的WiFi、GPS和加载设置。运行我的应用程序时,用户无需打开/关闭WiFi和GPS。(从通知栏)。是否存在用于收听GPS开/关的
广播接收器

这是不可能的。你不能随心所欲地控制/限制硬件的状态。这将是危险的,因为API中没有这样的API,所以不存在这样的API。

您可以注册一个
广播接收器
,用于收听
意图
操作
提供者\u更改\u操作
。这将在配置的位置提供程序更改时广播。你可以参考这个

您可以通过以下方式检测GPS的状态

看。向locationManager.addGpsStatusListener(gpsStatusListener)注册它


同时检查此项以便更好地理解。

您可以使用GpsStatus.Listener收听GPS状态 并向LocationManager注册

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.addGpsStatusListener(new android.location.GpsStatus.Listener()
{
    public void onGpsStatusChanged(int event)
    {
        switch(event)
        {
        case GPS_EVENT_STARTED:
            // do your tasks
            break;
        case GPS_EVENT_STOPPED:
            // do your tasks
            break;
        }
    }
});
您需要能够访问上下文(例如在“活动”或“应用程序”类中)


    • 您不能使用GpsStatus.Listener来执行此操作。你们必须使用广播接收机。使用LocationManager.PROVIDERS\u更改\u操作。不使用Intent.ACTION\u PROVIDER\u CHANE。
      祝你好运

      从API 19开始,您可以注册一个
      BroadcastReceiver
      ,用于收听intent action
      LocationManager.MODE\u CHANGED\u action

      参考:

      您可以使用

      try
      {
          int locationMode = android.provider.Settings.Secure.getInt(context.getContentResolver(), android.provider.Settings.Secure.LOCATION_MODE);
      } catch (android.provider.Settings.SettingNotFoundException e)
      {
          e.printStackTrace();
      }
      
      返回的值应为以下值之一:

      android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING
      android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
      android.provider.Settings.Secure.LOCATION_MODE_OFF
      android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY
      

      我做了大量的挖掘,发现
      addGpsStatusListener(gpsStatusListener)
      在API 24中被弃用。对我来说,这根本不管用!因此,这里有另一种解决方案

      如果在你的应用程序中,你想听到GPS状态的变化(我指的是用户的开/关)。使用广播肯定是最好的方法

      实施:

      /**
       * Following broadcast receiver is to listen the Location button toggle state in Android.
       */
      private BroadcastReceiver mGpsSwitchStateReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
      
              if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
                  // Make an action or refresh an already managed state.
              }
          }
      };
      
      不要忘了在片段/活动生命周期中高效地注册和注销它

      registerReceiver(mGpsSwitchStateReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
      
      例如,如果您使用的是
      片段
      ,请在
      onResume
      中注册它,并在
      onDestroy
      中注销它。此外,如果您将用户引导至设置以启用位置开关,则在
      桌面上注销
      将不起作用,因为您的活动将转到
      onPause
      并停止片段


      这个解决方案可能有很多答案,但这个很容易管理和使用。如果有,请提出您的解决方案。

      为此,我正在使用
      android.location.LocationListener

      `class MyOldAndroidLocationListener implements android.location.LocationListener {
          @Override public void onLocationChanged(Location location) { }
      
          //here are the methods you need
          @Override public void onStatusChanged(String provider, int status, Bundle extras) {}
          @Override public void onProviderEnabled(String provider) { }
          @Override public void onProviderDisabled(String provider) { }
      }`
      
      注意(来自):如果LocationListener已使用
      LocationManager.requestLocationUpdates(String、long、float、LocationListener)
      方法向LocationManager服务注册,则调用这些方法

      因为我使用融合的位置API来处理位置相关的东西,所以我只需要设置
      long minTime
      =1小时,
      float minDistance
      =1km,在
      requestLocationUpdates
      这使得我的应用程序的开销非常小


      当然,完成后不要忘记
      locationManager.removeUpdates

      在活动的
      onResume()方法中收听
      locationManager.PROVIDERS\u CHANGED\u ACTION
      事件:

      IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
      filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
      mActivity.registerReceiver(gpsSwitchStateReceiver, filter);
      
      mActivity.unregisterReceiver(gpsSwitchStateReceiver);
      
      将此
      BroadcastReceiver
      实例添加到您的活动中:

      private BroadcastReceiver gpsSwitchStateReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
          
                  if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.getAction())) {
      
                      LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
                      boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
                      boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
      
                      if (isGpsEnabled || isNetworkEnabled) {
                          // Handle Location turned ON
                      } else {
                          // Handle Location turned OFF
                      }
                  }
              }
          };
      
      在活动的
      onPause()方法中注销接收器:

      IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
      filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
      mActivity.registerReceiver(gpsSwitchStateReceiver, filter);
      
      mActivity.unregisterReceiver(gpsSwitchStateReceiver);
      
      在Kotlin中,尝试以下操作:

      添加一个扩展了BroadcastReceiver的类:

      class GPSCheck(private val locationCallBack: LocationCallBack) :
          BroadcastReceiver() {
          interface LocationCallBack {
              fun turnedOn()
              fun turnedOff()
          }
      
          override fun onReceive(context: Context, intent: Intent) {
              val locationManager =
                  context.getSystemService(LOCATION_SERVICE) as LocationManager
              if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) locationCallBack.turnedOn() else locationCallBack.turnedOff()
          }
      
      }
      
      然后,将其作为一个示例,如下所示:

      class MainActivity :AppCompatActivity(){
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_main)
      
              registerReceiver(GPSCheck(object : GPSCheck.LocationCallBack {
                  override fun turnedOn() {
                      Log.d("GpsReceiver", "is turned on")
                  }
      
                  override fun turnedOff() {
                      Log.d("GpsReceiver", "is turned off")
                  }
              }), IntentFilter(LocationManager.MODE_CHANGED_ACTION))
          }}
      

      我们可以使用LocationListener来了解GPS何时开启和何时关闭

      class HomeActivity : AppCompatActivity() {
          private var locManager: LocationManager? = null
          private val locListener: LocationListener =
              object : LocationListener {
                  override fun onLocationChanged(loc: Location) {
                  }
      
                  override fun onProviderEnabled(provider: String) {
                      Log.d("abc", "enable")
                  }
      
                  override fun onProviderDisabled(provider: String) {
                      Log.d("abc", "disable")
                  }
      
                  override fun onStatusChanged(
                      provider: String,
                      status: Int,
                      extras: Bundle
                  ) {
                  }
              }
      
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              locManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
          }
      
          override fun onResume() {
              super.onResume()
              startRequestingLocation()
          }
      
          override fun onStop() {
              super.onStop()
              try {
                  locManager!!.removeUpdates(locListener)
              } catch (e: SecurityException) {
              }
          }
      
          private fun startRequestingLocation() {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
                  checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
              ) {
                  requestPermissions(
                      arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                      PERMISSION_REQUEST
                  )
                  return
              }
              locManager!!.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locListener)
          }
      
          companion object {
              private const val PERMISSION_REQUEST = 1
          }
      }
      

      有关更多详细信息,请参阅此项目:

      每当用户更改gps状态时,我希望将其设置为以前的状态。我需要类似广播接收器的内容来收听android.net.conn.CONNECTIVITY\u更改,然后重新构造您的问题,因为这不是您要问的问题。您询问的是限制更改,而不是侦听更改。因此,从Nougat开始,
      addGpsStatusListener在API级别24中被弃用。改为使用registerGnssStatusCallback(GnssStatus.Callback)。
      根据Android文档,签入
      onReceive
      甚至可以通过不检查regex来简化:
      LocationManager.PROVIDERS\u CHANGED\u ACTION.equals(intent.getAction())
      您的意思是应该删除或改进该检查吗?可以通过不使用硬编码字符串“android.location.PROVIDERS\u changed”来更改该检查,但
      LocationManager.PROVIDERS\u changed\u操作
      @sud007:继续,除非被列入白名单,否则应用程序将不再收听广播接收器。因此,现在我们需要根据答案将接收方从清单声明更改为java/kotlin声明。现在,如果应用程序被关闭,而我打开了GPS,我没有其他方法可以让我的应用程序知道GPS已打开/关闭,我担心如果我遵循上述方法,我的应用程序将如何收听?@Rohit感谢您指出这一点!因为这个答案很久以前就提出了。如果您能够根据更新的文档推断出一些其他解决方案,那就太好了。我一定会尽快更新解决方案。谢谢我运行这个代码,当我手动打开gps时,它会工作,否则它不会显示任何东西,如果gps关闭,你知道为什么吗?我使用相同的代码。