如何检测用户是否在“设置”中关闭了位置信息?

时间:2019-08-01 09:49:56

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

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

代码示例: 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中检查接收器,因此您可以从Abstract Class中实例化对象。因此,而不是创建界面。

3 个答案:

答案 0 :(得分:2)

我实际上是用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内添加操作将无效。

答案 1 :(得分:0)

您可以为此目的使用广播接收器,状态更改后将触发该接收器。 选中此Answer

答案 2 :(得分:0)

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

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
}