如何实现 GPS 状态变化监听器
How to implement GPS Status change listener
在我的应用程序中,我每 5 分钟向服务器发送一次位置更新。为此,我正在使用 gms LocationListener
。这工作正常。我是运行这里面的一个服务。如果用户关闭 GPS,它将无法工作。因为它 运行 即使在打开 GPS 后它仍在服务中,它将等待完成 5 分钟的更新时间。所以我想要的是当用户打开 GPS 时它应该触发 onLocationUpdate 侦听器。
为此,我做了如下操作,我在我的服务中初始化了 GpsStatus.Listener
,并实现了它的 onStatusChange()
功能,但是在我将 GPS 状态从开到关/从关到开之后,该功能未触发。
代码
public class LocationUpdateService extends Service implements GpsStatus.Listener, com.google.android.gms.location.LocationListener{
onCreate(Bundle b){
super.onCreate();
registerGpsStatusListener();
}
private void registerGpsStatusListener() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.addGpsStatusListener(this);
}
@Override
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_STARTED:
Log.e(TAG, "onGpsStatusChanged started");
break;
case GpsStatus.GPS_EVENT_STOPPED:
Log.e(TAG, "onGpsStatusChanged stopped");
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
Log.e(TAG, "onGpsStatusChanged first fix");
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
Log.e(TAG, "onGpsStatusChanged status");
break;
}
}
@Override
public void onLocationChanged(Location location) {
//opertations
}
}
我的查询是:
1- 为什么方法 onGpsStatusChanged()
在更改 GPS 状态后没有调用。
2- 如何在 onLocationChanged()
方法中获取位置,以便我可以调用 onLocationUpdate()
方法。
注意:请不要推荐使用BroadcastReceiver
,因为它需要对我当前的代码进行大量修改。
我想您是想知道用户何时从他的设备打开或关闭 GPS。在那种情况下,您可以查看 this answer.This 是检测 GPS on/off 开关的唯一正确可靠的方法(至少它是唯一对我有用的方法)。
设置 GpsStatus.Listener 后,您需要将侦听器添加到 LocationManager。
locationManager.addGpsStatusListener(yourGpsStatusListener);
我建议您使用 google 位置服务而不是位置管理器。例如,使用此 LocationSimpleTracker
您可以轻松检测 GPS 状态和最后位置。
data class LocationSimpleTracker(val context: Context) {
private val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
private var locationCallback: LocationCallback? = null
fun detectGPS(onGPSChanged: (Boolean) -> Unit) {
locationCallback = object : LocationCallback() {
override fun onLocationAvailability(var1: LocationAvailability?) {
Timber.i("GPS enabled: ${var1?.isLocationAvailable}")
onGPSChanged(var1?.isLocationAvailable ?: false)
}
override fun onLocationResult(result: LocationResult?) {
Timber.i("New location: ${result?.lastLocation}")
}
}
fusedLocationProviderClient.requestLocationUpdates(buildLocationRequest(), locationCallback, null)
}
private fun buildLocationRequest(): LocationRequest = LocationRequest.create().apply {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 5000 //5 seconds
fastestInterval = 5000 //5 seconds
maxWaitTime = 1000 //1 seconds
}
fun stop() {
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}
}
并在您的 activity 中创建一个实例。祝你好运。
对于所有 Android 版本(最多为当前 30 API):
private val locationManager: LocationManager = context
.getSystemService(Context.LOCATION_SERVICE) as LocationManager
private var gpsStatusListener: Any? = null
private fun registerGpsStatusCallback() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val listener = object : GnssStatus.Callback() {
override fun onStarted() {
super.onStarted()
}
override fun onStopped() {
super.onStopped()
}
override fun onFirstFix(ttffMillis: Int) {
super.onFirstFix(ttffMillis)
}
override fun onSatelliteStatusChanged(status: GnssStatus) {
super.onSatelliteStatusChanged(status)
var inUse = 0
for (i in 0 until status.satelliteCount) {
if (status.usedInFix(i)) {
inUse++
}
}
}
}
locationManager.registerGnssStatusCallback(listener, backgroundHandler)
gpsStatusListener = listener
} else {
@Suppress("DEPRECATION")
val listener = GpsStatus.Listener { event ->
when (event) {
GpsStatus.GPS_EVENT_STARTED -> {}
GpsStatus.GPS_EVENT_STOPPED -> {}
GpsStatus.GPS_EVENT_FIRST_FIX -> {}
GpsStatus.GPS_EVENT_SATELLITE_STATUS -> {
val inUse = locationManager.getGpsStatus(null)?.satellites?.count { it.usedInFix() } ?: 0
}
}
}
@Suppress("DEPRECATION")
locationManager.addGpsStatusListener(listener)
gpsStatusListener = listener
}
}
private fun unregisterGpsStatusCallback() {
gpsStatusListener?.let { listener ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locationManager.unregisterGnssStatusCallback(listener as GnssStatus.Callback)
} else {
@Suppress("DEPRECATION")
locationManager.removeGpsStatusListener(listener as GpsStatus.Listener)
}
gpsStatusListener = null
}
}
在我的应用程序中,我每 5 分钟向服务器发送一次位置更新。为此,我正在使用 gms LocationListener
。这工作正常。我是运行这里面的一个服务。如果用户关闭 GPS,它将无法工作。因为它 运行 即使在打开 GPS 后它仍在服务中,它将等待完成 5 分钟的更新时间。所以我想要的是当用户打开 GPS 时它应该触发 onLocationUpdate 侦听器。
为此,我做了如下操作,我在我的服务中初始化了 GpsStatus.Listener
,并实现了它的 onStatusChange()
功能,但是在我将 GPS 状态从开到关/从关到开之后,该功能未触发。
代码
public class LocationUpdateService extends Service implements GpsStatus.Listener, com.google.android.gms.location.LocationListener{
onCreate(Bundle b){
super.onCreate();
registerGpsStatusListener();
}
private void registerGpsStatusListener() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.addGpsStatusListener(this);
}
@Override
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_STARTED:
Log.e(TAG, "onGpsStatusChanged started");
break;
case GpsStatus.GPS_EVENT_STOPPED:
Log.e(TAG, "onGpsStatusChanged stopped");
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
Log.e(TAG, "onGpsStatusChanged first fix");
break;
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
Log.e(TAG, "onGpsStatusChanged status");
break;
}
}
@Override
public void onLocationChanged(Location location) {
//opertations
}
}
我的查询是:
1- 为什么方法 onGpsStatusChanged()
在更改 GPS 状态后没有调用。
2- 如何在 onLocationChanged()
方法中获取位置,以便我可以调用 onLocationUpdate()
方法。
注意:请不要推荐使用BroadcastReceiver
,因为它需要对我当前的代码进行大量修改。
我想您是想知道用户何时从他的设备打开或关闭 GPS。在那种情况下,您可以查看 this answer.This 是检测 GPS on/off 开关的唯一正确可靠的方法(至少它是唯一对我有用的方法)。
设置 GpsStatus.Listener 后,您需要将侦听器添加到 LocationManager。
locationManager.addGpsStatusListener(yourGpsStatusListener);
我建议您使用 google 位置服务而不是位置管理器。例如,使用此 LocationSimpleTracker
您可以轻松检测 GPS 状态和最后位置。
data class LocationSimpleTracker(val context: Context) {
private val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
private var locationCallback: LocationCallback? = null
fun detectGPS(onGPSChanged: (Boolean) -> Unit) {
locationCallback = object : LocationCallback() {
override fun onLocationAvailability(var1: LocationAvailability?) {
Timber.i("GPS enabled: ${var1?.isLocationAvailable}")
onGPSChanged(var1?.isLocationAvailable ?: false)
}
override fun onLocationResult(result: LocationResult?) {
Timber.i("New location: ${result?.lastLocation}")
}
}
fusedLocationProviderClient.requestLocationUpdates(buildLocationRequest(), locationCallback, null)
}
private fun buildLocationRequest(): LocationRequest = LocationRequest.create().apply {
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 5000 //5 seconds
fastestInterval = 5000 //5 seconds
maxWaitTime = 1000 //1 seconds
}
fun stop() {
fusedLocationProviderClient.removeLocationUpdates(locationCallback)
}
}
并在您的 activity 中创建一个实例。祝你好运。
对于所有 Android 版本(最多为当前 30 API):
private val locationManager: LocationManager = context
.getSystemService(Context.LOCATION_SERVICE) as LocationManager
private var gpsStatusListener: Any? = null
private fun registerGpsStatusCallback() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val listener = object : GnssStatus.Callback() {
override fun onStarted() {
super.onStarted()
}
override fun onStopped() {
super.onStopped()
}
override fun onFirstFix(ttffMillis: Int) {
super.onFirstFix(ttffMillis)
}
override fun onSatelliteStatusChanged(status: GnssStatus) {
super.onSatelliteStatusChanged(status)
var inUse = 0
for (i in 0 until status.satelliteCount) {
if (status.usedInFix(i)) {
inUse++
}
}
}
}
locationManager.registerGnssStatusCallback(listener, backgroundHandler)
gpsStatusListener = listener
} else {
@Suppress("DEPRECATION")
val listener = GpsStatus.Listener { event ->
when (event) {
GpsStatus.GPS_EVENT_STARTED -> {}
GpsStatus.GPS_EVENT_STOPPED -> {}
GpsStatus.GPS_EVENT_FIRST_FIX -> {}
GpsStatus.GPS_EVENT_SATELLITE_STATUS -> {
val inUse = locationManager.getGpsStatus(null)?.satellites?.count { it.usedInFix() } ?: 0
}
}
}
@Suppress("DEPRECATION")
locationManager.addGpsStatusListener(listener)
gpsStatusListener = listener
}
}
private fun unregisterGpsStatusCallback() {
gpsStatusListener?.let { listener ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
locationManager.unregisterGnssStatusCallback(listener as GnssStatus.Callback)
} else {
@Suppress("DEPRECATION")
locationManager.removeGpsStatusListener(listener as GpsStatus.Listener)
}
gpsStatusListener = null
}
}