【问题标题】:How to implement GPS Status change listener如何实现 GPS 状态变化监听器
【发布时间】:2015-09-30 07:16:47
【问题描述】:

在我的应用程序中,我每 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- 为什么更改 GPS 状态后方法 onGpsStatusChanged() 没有调用。

2- 如何在onLocationChanged() 方法中获取位置,以便调用onLocationUpdate() 方法。

注意:请不要推荐使用BroadcastReceiver,因为它需要对我当前的代码进行大量代码修改。

【问题讨论】:

  • 我猜你可能不喜欢这个答案。如果有兴趣使用 ReactiveLocation github.com/mcharmas/Android-ReactiveLocation
  • GPS 状态监听器是关于 GPS 服务开启一段时间后内部发生的情况。要查看 GPS 是否已打开,您需要 LocationListener.isProviderEnabled()。看这里的答案:stackoverflow.com/questions/18259039/…
  • 第二个问题我不太明白。 (Location location) 是您接收新位置的地方。然后你就可以处理数据,做location.getLatitude() 之类的事情了……

标签: android gps location


【解决方案1】:

我认为您想知道用户何时从他的设备打开或关闭 GPS。在这种情况下,您可以查看this 答案。这是检测 GPS 开/关开关的唯一正确可靠的方法(至少它是唯一对我有用的方法)。

【讨论】:

  • 我正在寻找比广播接收器更好的解决方案
  • 更好的解决方案?在什么意义上更好?我花了很长时间研究 GPS,但找不到更好的解决方案。广播接收器解决方案是最可靠且运行良好的。如果你找到了,请发布它。
  • 但是 PROVIDERS_CHANGED 广播会在任何位置提供商连接时触发,不是吗
  • @varunkr "更好" == 更简单 ;)
  • @varunkr:当你打开一个假的 gps 应用时,你无法监听 gps 与广播接收器的切换。
【解决方案2】:

设置 GpsStatus.Listener 后,您需要将侦听器添加到 LocationManager。

locationManager.addGpsStatusListener(yourGpsStatusListener);

【讨论】:

  • 对于 Android 24 API (N) 及更高版本为 locationManager.registerGnssStatusCallback(listener)
【解决方案3】:

我建议您使用谷歌位置服务而不是位置管理器。例如,使用此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)
    }
}

并在您的活动中创建一个实例。祝你好运。

【讨论】:

    【解决方案4】:

    适用于所有 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 2011-01-31
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多