根据这个:http://developer.android.com/preview/features/runtime-permissions.html#coding一个应用程序可以检查运行时权限和请求权限,如果它还没有被授予。弹出如下对话框:
如果用户拒绝一个重要的权限,在我看来,应用程序应该显示一个解释为什么需要权限和什么影响拒绝。该对话框有两个选项:
重试(再次请求许可)
拒绝(应用程序将工作没有该许可)。
但是,如果用户选中“Never ask again”,则不应该显示带有解释的第二个对话框,特别是如果用户之前已经拒绝了一次。
现在的问题是:我的应用程序如何知道用户是否选中了Never ask again?IMO onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)没有给我这个信息。
第二个问题是:谷歌是否计划在权限对话框中包含一个自定义消息,以解释为什么应用程序需要权限?这样就不会出现第二个对话框,这肯定会带来更好的用户体验。
相反,你会收到回调onRequestPermissionsResult()作为PERMISSION_DENIED当你再次请求权限时,而落在shouldShowRequestPermissionRationale()的错误条件下
来自Android文档:
When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again. In that case, any time an app uses requestPermissions() to ask for that permission again, the system immediately denies the request. The system calls your onRequestPermissionsResult() callback method and passes PERMISSION_DENIED, the same way it would if the user had explicitly rejected your request again. This means that when you call requestPermissions(), you cannot assume that any direct interaction with the user has taken place.
为了准确地回答这个问题,当用户按下“永不再问”时会发生什么?
重写的方法/函数
onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray)
grantResult数组显示为空,你可以在这里做些什么?但不是最好的做法。
如何处理“永不再问”?
我正在使用Fragment,它需要READ_EXTERNAL_STORAGE权限。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
when {
isReadPermissionsGranted() -> {
/**
* Permissions has been Granted
*/
getDirectories()
}
isPermissionDeniedBefore() -> {
/**
* User has denied before, explain why we need the permission and ask again
*/
updateUIForDeniedPermissions()
checkIfPermissionIsGrantedNow()
}
else -> {
/**
* Need to ask For Permissions, First Time
*/
checkIfPermissionIsGrantedNow()
/**
* If user selects, "Dont Ask Again" it will never ask again! so just update the UI for Denied Permissions
*/
updateUIForDeniedPermissions()
}
}
}
其他的函数是微不足道的。
// Is Read Write Permissions Granted
fun isReadWritePermissionGranted(context: Context): Boolean {
return (ContextCompat.checkSelfPermission(
context as Activity,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED) and
(ContextCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED)
}
fun isReadPermissionDenied(context: Context) : Boolean {
return ActivityCompat.shouldShowRequestPermissionRationale(
context as Activity,
PermissionsUtils.READ_EXTERNAL_STORAGE_PERMISSIONS)
}
shouldShowRequestPermissionRationale根据之前权限请求中的用户首选项返回true或false。
如果用户只是拒绝权限(不是永远)shouldShowRequestPermissionRationale将返回true。如果永远拒绝许可,则返回false。窍门是即使用户允许了权限shouldShowRequestPermissionRationale也会返回false。
因此,我们可以结合这两个条件来得到永不再问的选择与否。
因此,如果用户不允许权限,并且shouldShowRequestPermissionRationale返回false,那么这意味着用户选择永远不会再次请求权限。
https://stackoverflow.com/a/58114769/5151336
您可以使用if (ActivityCompat。shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)方法来检测never ask是否被检查。
更多参考:检查这个
检查是否使用了多个权限:
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
解释()方法
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
上面的代码还将显示对话框,这将重定向到用户的应用程序设置屏幕,在那里他可以给予权限,如果选中了“永不再问”按钮。