
本文旨在帮助开发者解决在 Android 11 (API level 30) 及以上版本中获取存储权限的问题。由于 Android 11 引入了分区存储机制,传统的存储权限申请方式可能不再适用。本文将详细介绍如何在 Android 11 中正确申请和处理存储权限,包括清单文件配置、权限请求以及运行时权限处理等关键步骤,并提供相应的代码示例,助您顺利完成应用适配。
Android 11 引入了分区存储 (Scoped Storage) 机制,旨在增强用户隐私和数据安全。这意味着应用程序默认情况下只能访问其自身创建的文件以及特定的公共目录。如果您的应用需要访问更广泛的外部存储,您需要进行额外的权限申请和处理。
首先,需要在 AndroidManifest.xml 文件中进行必要的配置。
重要: android:requestLegacyExternalStorage="true" 在 targetSdkVersion 大于等于 30 时将不再生效。因此,依赖此属性来获取传统存储权限的方法不再可行。
如果您需要申请 "所有文件访问权限" (All files access),则无需声明任何存储权限。但是,您需要在代码中检查并请求 MANAGE_EXTERNAL_STORAGE 权限。
根据您的应用需求,选择合适的权限请求方式。
访问应用特定目录和媒体文件: 这是推荐的方式,应用应该尽可能使用分区存储提供的API,例如 MediaStore API 来访问媒体文件。
申请 "所有文件访问权限" (All files access): 仅当您的应用的核心功能需要访问设备上的所有文件时,才应申请此权限。例如,文件管理器、备份应用等。
以下是申请 "所有文件访问权限" 的步骤:
if (!Environment.isExternalStorageManager()) {
// 未授权,需要请求权限
}Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", this.getPackageName(), null);
intent.setData(uri);
startActivity(intent);这段代码会打开系统设置界面,允许用户手动授予应用 "所有文件访问权限"。
在 Android 6.0 (API level 23) 及以上版本中,需要在运行时检查和请求权限。对于 Android 11,READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限在 targetSdkVersion 大于等于 30 时,行为会发生变化。
如果您的应用需要兼容旧版本,可以使用以下代码进行权限请求:
private static final int REQUEST_CODE_PERMISSION = 1;
private void requestStoragePermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Android 11 及以上
if (!Environment.isExternalStorageManager()) {
try {
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.fromParts("package", getPackageName(), null));
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
} catch (Exception e) {
Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, REQUEST_CODE_PERMISSION);
}
} else {
// 已经拥有所有文件访问权限
// 执行相关操作
}
} else {
// Android 10 及以下
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_PERMISSION);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// 用户授予了所有文件访问权限
// 执行相关操作
} else {
// 用户拒绝了权限
// 进行相应的处理,例如提示用户或禁用相关功能
}
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授予了权限
// 执行相关操作
} else {
// 用户拒绝了权限
// 进行相应的处理,例如提示用户或禁用相关功能
}
}
}注意事项:
在 Android 11 及以上版本中获取存储权限需要特别注意分区存储机制的变化。您需要根据应用的需求选择合适的权限申请方式,并正确处理运行时权限。尽量使用分区存储提供的 API,避免过度申请权限,以保护用户隐私。 确保您的应用遵循 Android 的最佳实践,并提供清晰的用户体验。
以上就是Android 11 存储权限获取指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号