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