我当前的应用程序有一个FeedbackFragment
,它使用支持库中的Fragment
并提供一个复选框,允许用户选择性地发送带有反馈的系统日志。由于将日志附加到外发电子邮件需要访问外部存储(WRITE_EXTERNAL_STORAGE
权限),因此我必须在要求FeedbackFragment
时请求许可。如果用户拒绝写入外部存储的权限,我想禁用/隐藏“包含系统日志”#39;复选框,但我希望此屏幕的其余功能正常工作(在Marshmallow设备上工作正常,BTW)。我已经根据官方Android文档编写了相应的方法,以及许多SO文章的组合,这就是我目前所拥有的。请注意,我并没有停留在“拒绝”的任何断点处。这段代码中的分支。
以下所有逻辑都是在checkExternalStoragePermissions()
onCreateView()
来电中创建的
我错过了什么?
private void checkExternalStoragePermissions() {
if (ContextCompat.checkSelfPermission(getContext(), WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
canSendAttachments = true;
systemLogsCheckbox.setEnabled(true);
} else {
requestExternalStoragePermission();
}
}
private void requestExternalStoragePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), WRITE_EXTERNAL_STORAGE)) {
new SnackBar.Builder(getActivity())
.withMessage(getString(R.string.write_external_storage_permission_rationale))
.withDuration(SnackBar.PERMANENT_SNACK)
.withActionMessage("OK")
.withOnClickListener(new SnackBar.OnMessageClickListener() {
@Override
public void onMessageClick(Parcelable token) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{WRITE_EXTERNAL_STORAGE},
WRITE_TO_EXTERNAL_STORAGE_PERMISSION);
}
})
.withTextColorId(R.color.almanac_red_tab_highlight)
.show();
} else {
ActivityCompat.requestPermissions(getActivity(),
new String[]{WRITE_EXTERNAL_STORAGE}, WRITE_TO_EXTERNAL_STORAGE_PERMISSION);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
if (requestCode == WRITE_TO_EXTERNAL_STORAGE_PERMISSION) {
if ((grantResults.length == 1) && (grantResults[0] == PERMISSION_GRANTED)) {
canSendAttachments = true;
systemLogsCheckbox.setEnabled(true);
} else {
canSendAttachments = false;
systemLogsCheckbox.setEnabled(false);
systemLogsCheckbox.setChecked(false);
}
} else
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
答案 0 :(得分:2)
如果您使用Fragment
拨打电话,则应致电FragmentCompat.requestPermissions
,以便回调路由您的片段而不是您的活动。
您可能需要将此文件添加到gradle文件中,因为FragmentCompat
位于support-v13 lib中。
compile 'com.android.support:support-v13:23.1.1'
答案 1 :(得分:0)
首先,您需要在OnRequestPermissionsResultCallback
中实施Listener
类的ActivityCompat
Activity
并覆盖void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
方法,以检查用户是否允许或拒绝该权限
你可以这样做:
int REQUEST_STORAGE = 1;
private void checkExternalStoragePermissions() {
if (hasStoragePermissionGranted()) {
canSendAttachments = true;
systemLogsCheckbox.setEnabled(true);
} else {
requestExternalStoragePermission();
}
}
public boolean hasStoragePermissionGranted(){
return ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}
public void requestExternalStoragePermission() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_STORAGE);
}
}
当用户允许或拒绝来自运行时权限对话框的权限时,将调用onRequestPermissionsResult()
方法。
您还可以处理用户选中时从未显示“运行时权限”对话框的情况。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == REQUEST_STORAGE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Storage permission is enabled
canSendAttachments = true;
systemLogsCheckbox.setEnabled(true);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivtity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//User has deny from permission dialog
Snackbar.make(mainLayout, getResources().getString("Please enable storage permission"),
Snackbar.LENGTH_INDEFINITE)
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_STORAGE);
}
})
.show();
} else {
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
Snackbar.make(mainLayout, getResources().getString("Please enable permission from settings"),
Snackbar.LENGTH_INDEFINITE)
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
})
.show();
}
}
}
希望它对你有所帮助。
答案 2 :(得分:0)
虽然 @iagreen 的答案很接近,但我最初遇到的问题是因为我在代码中使用了ActivityCompat
版本的相应方法。一旦我从方法调用中删除了该前缀并使用了Fragment
类中的相应方法,一切都按照我现在的预期进行,原始问题已经解决。
话虽如此,我也在研究如何使用ContentProvider
来完全否定WRITE_EXTERNAL_STORAGE
权限的需要,正如 @Chris Stratton 所建议的那样