场合
我的一个片段访问相机。所以当然我需要首先检查我的活动中的权限,然后再重定向到它。如果用户拒绝该权限,则活动完成并将其重定向到他所在的上一个活动
此外,我想在活动开始时显示一个不同的片段,并检测到该权限被永久拒绝。 (Android权限对话框中的小复选框“Never ask again”)
问题
我找不到正确的检测方法,只是一次拒绝了许可,或者上次检查了“永不再问”复选框并永久拒绝了许可。
请记住,我不想知道在onRequestPermissionsResult回调中。如果当前授予,拒绝或永久拒绝许可,我需要在onCreate of my Activity中知道。
我尝试了什么
ActivityCompat#shouldShowRequestPermissionRationale
似乎发现过去是否拒绝了许可。如果它只被拒绝一次而不是永久性,它也会返回true。
PermissionChecker#checkPermission()
似乎没有注意到永久和只有一次拒绝许可状态之间的任何区别。
问题
是否有任何方法可以检测,是否仍然可以请求许可,或者是否被永久拒绝?
答案 0 :(得分:5)
是否有任何方法可以检测到权限是否被拒绝但是可以 仍被请求或是否被永久拒绝?
不幸的是,当用户选择" 从不再问及"
时,没有正式的API可用于检测权限是否被永久拒绝有一项工作使用shouldShowRequestPermissionRationale
。创建一个默认值为false
的SharedPreference,并在其中存储由shouldShowRequestPermissionRationale
返回的值。在更新值之前,请检查值集是否为true
。如果是true
,则不要更新。
每当您想要检查权限时,请获取SharedPreference
的值和shouldShowRequestPermissionRationale
返回的当前值。如果shouldShowRequestPermissionRationale
返回false
但SharedPreference
的值为true
,则可以推断用户已选择Never ask again
。
您可以参考我描述此方法的blog。
答案 1 :(得分:0)
您可以通过
检查权限if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)){}
通常我会使用以下内容检查权限,
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(TrackActivity.this, Manifest.permission.CALL_PHONE)) {
ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
} else if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)) {
} else {
ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
}
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(Manifest.permission.CALL_PHONE, true);
editor.apply();
}
答案 2 :(得分:0)
您可以使用Dexter库,该库使处理android权限更加容易。我这样解决了这个问题:
private void checkUserPermission() {
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CALL_PHONE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CAMERA
).withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
//check if all permission are granted
if (report.areAllPermissionsGranted()) {
initSocket();
} else {
List<PermissionDeniedResponse> responses = report.getDeniedPermissionResponses();
StringBuilder permissionsDenied = new StringBuilder("Permissions denied: ");
for (PermissionDeniedResponse response : responses) {
permissionsDenied.append(response.getPermissionName()).append(" ") ;
}
showInfoMessageToast(permissionsDenied.toString());
}
if (report.isAnyPermissionPermanentlyDenied()) {
//permission is permanently denied navigate to user setting
AlertDialog.Builder dialog = new AlertDialog.Builder(HomeActivity.this)
.setTitle("Need Permissions")
.setMessage("This application need to use some permissions, " +
"you can grant them in the application settings.")
.setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
}
})
.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
dialog.show();
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
})
.onSameThread()
.check();
}
以这种方式创建导入后
import com.karumi.dexter.Dexter;
针对您要实现的目标进行调整,应该可以解决您的问题。
答案 3 :(得分:0)
shouldShowRequestPermissionRationale
根据先前权限请求中的用户首选项返回true或false。
如果用户刚刚被拒绝许可(不是永远),则shouldShowRequestPermissionRationale
将返回true
。
如果永远拒绝许可,则返回false
。
诀窍在于,即使是用户允许的权限,shouldShowRequestPermissionRationale
也会返回false
。
因此,我们可以结合两个条件来选择是否再次选择“不询问”。
因此,如果用户未获得许可,并且shouldShowRequestPermissionRationale
返回false
,则意味着用户选择不再询问该许可。
答案 4 :(得分:0)
要检测用户是否被永久拒绝该许可,我们不需要使用任何其他逻辑
if (ActivityCompat.shouldShowRequestPermissionRationale(UserEditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)){
// not permanently denied
}
else {
// permanently denied
}
就是这样。
答案 5 :(得分:0)