![](/img/trans.png)
[英]How to detect when user turns off GPS with FusedLocationProviderClient?
[英]How to detect when user turn on/off GPS state?
我想阻止用戶從我的應用程序更改 WiFi、GPS 和加載設置。 用戶在運行我的應用程序時不需要打開/關閉 WiFi 和 GPS。(來自通知欄)。 是否有任何BroadcastReceiver
可以打開/關閉收聽 GPS?
好吧,我做了很多挖掘,發現 API 24 中不推薦使用addGpsStatusListener(gpsStatusListener)
。對我來說,這甚至不起作用! 所以,這是另一個替代解決方案。
如果在您的應用程序中,您想收聽 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.
}
}
};
不要忘記在 Fragment/Activity Lifecycle 中有效地注冊和取消注冊。
registerReceiver(mGpsSwitchStateReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
例如,如果您使用的是Fragment
,請在onResume
注冊它並在onDestroy
取消注冊。 此外,如果您將用戶引導至設置以啟用位置開關,則在onStop
取消注冊將不起作用,因為您的活動將轉到onPause
並且 Fragment 已停止。
這個解決方案可能有很多答案,但是這個很容易管理和使用。 提出您的解決方案(如果有)。
您可以使用 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;
}
}
});
您需要有權訪問上下文(例如在“活動”或“應用程序”類中)。
在您的活動的onResume()
方法中收聽LocationManager.PROVIDERS_CHANGED_ACTION
事件:
IntentFilter filter = new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION);
filter.addAction(Intent.ACTION_PROVIDER_CHANGED);
mActivity.registerReceiver(gpsSwitchStateReceiver, filter);
將此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()
方法中取消注冊接收器:
mActivity.unregisterReceiver(gpsSwitchStateReceiver);
這不可能。 您無法隨心所欲地控制/限制硬件的狀態。 這在 API 中是很危險的,因此不存在這樣的 API。
在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))
}}
你可以注冊一個BroadcastReceiver
來監聽Intent
Action PROVIDERS_CHANGED_ACTION
。 這將在配置的位置提供程序更改時廣播。 你可以參考這個鏈接。
您可以通過以下方式檢測 GPS 的狀態。
看看GpsStatus.Listener 。 使用 locationManager.addGpsStatusListener(gpsStatusListener) 注冊它。
另請檢查此 SO 鏈接以更好地理解。
我們可以使用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
}
}
有關更多詳細信息,請參閱此項目: https : //github.com/pR0Ps/LocationShare
從 API 19 開始,您可以注冊一個BroadcastReceiver
來監聽意圖操作LocationManager.MODE_CHANGED_ACTION
參考: https : //developer.android.com/reference/android/location/LocationManager.html#MODE_CHANGED_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
您不能使用 GpsStatus.Listener 來執行此操作。 您必須使用廣播接收器。 使用 LocationManager.PROVIDERS_CHANGE_ACTION。 不使用 Intent.ACTION_PROVIDER_CHANE。 祝你好運 !
我為此目的使用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)
方法注冊到位置管理器服務,則會調用這些方法
由於我將 Fused Location API 用於與位置相關的內容,因此我只是在requestLocationUpdates
設置了long minTime
= 1 小時, float minDistance
= 1km,這對我的應用程序的開銷很小。
而且,當然,完成后不要忘記locationManager.removeUpdates
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.