我已经实现了运行时权限。出于测试目的,我已经拒绝了位置许可,然后我再次拒绝了“永不再问”复选框的权限。 现在有问题了。正在从系统中反复调用OnRequestPermissionResult。为此,我无法在屏幕上正确显示对话框或小吃栏。这是我的实施。问题在哪里?
检查位置许可
override fun onResume() {
super.onResume()
if (checkLocationPermission())
startLocationUpdates()
updateUI()
}
这是我的位置更新通话
@SuppressLint("MissingPermission")
private fun startLocationUpdates() {
// Begin by checking if the device has the necessary location settings.
mLocationSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this, {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
updateUI()
})
.addOnFailureListener(this, {
handlingLocationClientSettingsFailure(it)
});
}
private fun handlingLocationClientSettingsFailure(it: Exception) {
val apiException = it as ApiException
when (apiException.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
try {
Lg.d(TAG, "Inside start location update method FAILURE: REQUIRED")
// Show the dialog by calling startResolutionForResult(), and check the
// result in onActivityResult().
val rae = it as ResolvableApiException
rae.startResolutionForResult(this@MainActivity, REQUEST_CHECK_SETTINGS);
} catch (sie: IntentSender.SendIntentException) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
val errorMessage = "Location settings are inadequate, and cannot be " +
"fixed here. Fix in Settings.";
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
mRequestingLocationUpdates = false;
}
}
updateUI()
}
override fun onStop() {
super.onStop()
stopLocationUpdates()
}
private fun stopLocationUpdates() {
if (!mRequestingLocationUpdates) {
Lg.d(TAG, "Permission Denied! So No op!!!")
return
}
mFusedLocationClient.removeLocationUpdates(mLocationCallback)
.addOnCompleteListener(this) { mRequestingLocationUpdates = false }
}
private val MY_PERMISSIONS_REQUEST_LOCATION = 99;
private fun startLocationPermissionRequest() {
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
MY_PERMISSIONS_REQUEST_LOCATION);
}
private fun checkLocationPermission(): Boolean {
if (ContextCompat.checkSelfPermission(this@MainActivity, ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this@MainActivity, ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
showSnackbar(R.string.location_permission_rationale,
android.R.string.ok,
View.OnClickListener {
startLocationPermissionRequest()
})
} else {
// No explanation needed, we can request the permission.
startLocationPermissionRequest()
}
return false
} else {
// Permission has already been granted
return true
}
}
@SuppressLint("NeedOnRequestPermissionsResult")
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<out String>, grantResults: IntArray) {
when (requestCode) {
MY_PERMISSIONS_REQUEST_LOCATION -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this@MainActivity, ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this@MainActivity, ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
) {
setLocationEnabled()
startLocationUpdates()
}
} else {
val showRationale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
shouldShowRequestPermissionRationale(permissions[0])
} else {
TODO("VERSION.SDK_INT < M")
}
if (!showRationale) {
// user also CHECKED "never ask again"
// you can either enable some fall back,
// disable features of your app
// or open another dialog explaining
// again the permission and directing to
// the app setting
showingNecessaryMsgForLocationPermissionDenied()
} else {
// user did NOT check "never ask again"
// this is a good place to explain the user
// why you need the permission and ask if he wants
// to accept it (the rationale)
}
}
return
}
// other 'case' lines to check for other
// permissions this app might request
}
}
private fun showingNecessaryMsgForLocationPermissionDenied() {
Lg.d("TestTag", "Called")
MaterialDialog.Builder(this)
.title("Permission")
.content(R.string.permission_denied_explanation)
.onPositive { dialog, which ->
// Build intent that displays the App settings screen.
val intent = Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
data = Uri.fromParts("package", APPLICATION_ID, null)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
startActivity(intent)
}
.positiveText(R.string.ok)
.show()
}
在这个showsNecessaryMsgForLocationPermissionDenied()函数中我放了一个日志,在我的logcat中我看到这个函数一次又一次地调用。怎么阻止它?这是logcat screentshot
我想在用户拒绝权限时显示此对话框。但是我不能顺利地解决上述问题。
注意:我已经测试了位置更新项目的Google存储库。同样的问题
答案 0 :(得分:4)
此方法可以启动一项活动,允许用户选择授予哪些权限以及拒绝哪些权限。因此,您应该准备好您的活动可以暂停和恢复。 此外,授予某些权限可能需要重新启动您的应用。
在此代码中,您在checkLocationPermission()
中呼叫onResume()
。然后从checkLocationPermission()
来电requestPermissions
进入onPasue()
中的活动。在onRequestPermissionsResult()
之后,再次调用onResume()
,创建infinte循环。
我建议使用布尔变量来决定是否需要调用checkLocationPermission()
。
var isRequestRequired = true;
override fun onResume() {
super.onResume()
if (isRequestRequired && checkLocationPermission())
startLocationUpdates()
updateUI()
}
然后在isRequestRequired
showingNecessaryMsgForLocationPermissionDenied()
更新为false
isRequestRequired = false
showingNecessaryMsgForLocationPermissionDenied()
这会阻止onResume()
一次又一次地呼叫checkLocationPermission()