【问题标题】:How to detect if user turned off Location in Settings?如何检测用户是否在设置中关闭了位置?
【发布时间】:2019-12-09 21:22:28
【问题描述】:

我想检测用户是否在运行时关闭了位置。我可以检查他是否打开了它,或者在应用程序启动之前用户是否关闭了该位置,但我无法检查他是否在之后将其关闭。

代码示例: MapEntity 扩展 LocationListener

class MapViewer(a: MainActivity, parentView: ViewGroup) : MapEntity(a, parentView) {

    override fun onProviderEnabled(provider: String?) {
        activity.hideGpsSnackbar()
    }

    override fun onProviderDisabled(provider: String?) {
        activity.showGpsSnackbar()
    }

}

对于实时 GPS 位置检查,我使用的是GnssStatus.Callback()

更新:

我根据下面的答案创建了BroadcastReceiver

abstract class GPSReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        try {
           val locationManager = context.getSystemService(LOCATION_SERVICE) as LocationManager

             if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    onGpsChanged(true)
                } else {
                    onGpsChanged(false)
                }
            } catch (ex: Exception) {
                App.log("IsGPSEnabled: $ex")
            }

        }

        abstract fun onGpsChanged(isEnabled: Boolean)
    }

我的一项活动中的代码:

private val gpsStatusReceiver = object : GPSReceiver() {

     override fun onGpsChanged(isEnabled: Boolean) {
         if (isEnabled){
             hideGpsSnackbar()
         } else {
             showGpsSnackbar()
         }
     }
}

override fun onStart() {
    super.onStart()
    registerReceiver(gpsStatusReceiver, IntentFilter())
}

override fun onStop() {
    super.onStop()
    unregisterReceiver(gpsStatusReceiver)
}

更新

如果要支持 Android 6.0,则不能使用抽象类。因为它将尝试从 AndroidManifest 中定义的此类创建对象。 Android 8.0+ 不会检查 AndroidManifest 中的接收器,因此您可以从抽象类中实例化对象。因此,与其创建接口。

【问题讨论】:

    标签: android kotlin android-location android-maps-v2 android-gps


    【解决方案1】:

    我实际上是用BroadcastReceiver 来做的。

    我可以分享我的代码;它是 java,但我认为您可以轻松地将其转换为 kotlin。

    1. 创建Broadcastreceiver

    例子:

    public class GPSBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
                if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    //isGPSEnabled = true;
                } else {
                    //isGPSEnabled = false;
                }
            }catch (Exception ex){
            }
        }
    }
    
    1. 将您的BroadcastReceiver 添加到manifest

    例子:

        <receiver android:name=".others.GPSBroadcastReceiver">
            <intent-filter>
                <action android:name="android.location.PROVIDERS_CHANGED" />
    
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
    

    然后(就我而言)我在ApplicationContext 中管理它,如下所示:

    private GPSBroadcastReceiver gpsBroadcastReceiver = new GPSBroadcastReceiver();
    
    @Override
    public void onCreate() {
        ....
        registerReceiver(gpsBroadcastReceiver, new IntentFilter());
    }
    
    @Override
    public void onTerminate() {
        ...
        unregisterReceiver(gpsBroadcastReceiver);
    }
    

    这只是一个例子,可能还有其他方法,但实际上我对那个没问题;祝你好运!

    编辑:

    尝试在清单中添加此权限

    <uses-permission android:name="android.permission.ACCESS_GPS" />
    

    编辑: 对于 Android 8.0+,请像这样注册您的 BroadcastReceiver

    registerReceiver(gpsBroadcastReceiver,IntentFilter("android.location.PROVIDERS_CHANGED"))
    

    AndroidManifest 中添加操作将不起作用。

    【讨论】:

    • @martin1337 检查编辑,可能我忘了添加权限
    • 添加了权限,但仍然没有
    • @martin1337 你的日志是用logcat写的吗?
    • 不。我没有从接收者那里得到任何日志。我已经稍微更新了我的解决方案。 Receiver 是抽象类,重写方法 onGpsChanged 应该将状态返回给我的活动。但什么也没发生。
    • @martin1337 如果您将 onGpsChanged(bool) 替换为日志,您会得到什么?尝试调试;在你的 onReceive 中放置一个断点并检查它是否被调用以及何时
    【解决方案2】:

    您可以为此目的使用广播接收器,当状态更改时将触发该接收器。 检查这个Answer

    【讨论】:

    • 为什么onProviderEnabledonProviderDisabled 在这里不起作用?
    【解决方案3】:

    请使用以下方法启用位置设置:

    LocationServices
            .getSettingsClient(this)
            .checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(this, object : OnSuccessListener<LocationSettingsResponse> {    
                    override fun onSuccess(locationSettingsResponse: LocationSettingsResponse) {
                        Log.i(TAG, "LocationManager: All location settings are satisfied.");
                        mLocationCallback?.let {
                            fusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                        }
                        //updateUI();
                    }
            })
            .addOnFailureListener(this, object : OnFailureListener {
                    override fun onFailure(e: Exception) {
                        var statusCode = (e as ApiException).getStatusCode()
                        when (statusCode) {
                            LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                                try {
                                    // Show the dialog by calling startResolutionForResult(), and check the
                                    // result in onActivityResult().
                                    var rae = e as ResolvableApiException;
                                    rae.startResolutionForResult(this@BaseLocationActivity, REQUEST_CHECK_SETTINGS);
                                } catch (sie: IntentSender.SendIntentException) {
                                    Log.i(TAG, "PendingIntent unable to execute request.");
                                }
                            }
                            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                                mRequestingLocationUpdates = false;
                            }    
                        }
                    }
            })
    

    创建位置请求

    private fun createLocationRequest(interval: Long, distance: Float = 0f) {
        mLocationRequest = LocationRequest()
        mLocationRequest.interval = interval
        mLocationRequest.fastestInterval = interval
    
        Log.v(TAG, "distance => $distance")
        if (distance > 0) {
            mLocationRequest.smallestDisplacement = distance
        }
        mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      相关资源
      最近更新 更多