赞
踩
Android11系统对应用写入权限做了严格的限制。本文介绍如何获取文件读写权限。项目中 build.gradle 的targetSdkVersion >= 29 ,会出现读写问题。
当targetSdkVersion = 29,通过设置requestLegacyExternalStorage=“true”,还能解决。
当targetSdkVersion = 30后,需要申请所有文件权限才能获取到写入权限。
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
- tools:ignore="ScopedStorage" /><!--add 2022-2-11 Android11-->
- <application
- ...
- android:requestLegacyExternalStorage="true"
- ...
- >
1.Android 6.0之上Android11以下申请权限
- if (Build.VERSION.SDK_INT >= 23) {// 6.0
- String[] perms = {
- Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_STATE};
- for (String p : perms) {
- int f = ContextCompat.checkSelfPermission(SafeKeyToolActivity.this, p);
- Log.d("---", String.format("%s - %d", p, f));
- if (f != PackageManager.PERMISSION_GRANTED) {
- requestPermissions(perms, 0XCF);
- break;
- }
- }
- }
跳转系统设置界面,用户授权获取权限。
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !isRefuse) {// android 11 且 不是已经被拒绝
- // 先判断有没有权限
- if (!Environment.isExternalStorageManager()) {
- Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
- intent.setData(Uri.parse("package:" + getPackageName()));
- startActivityForResult(intent, 1024);
- }
- }
-
- // 带回授权结果
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == 1024 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- // 检查是否有权限
- if (Environment.isExternalStorageManager()) {
- isRefuse = false;
- // 授权成功
- } else {
- isRefuse = true;
- // 授权失败
- }
- }
- }
对于部分手机如小米手机,即使获取了所有文件的管理权限,依旧访问不到Android/data目录,如图:
尝试解决办法:
只在外部存储的应用私有目录下,用直接路径读写文件。
访问或者共享媒体文件,使用MediaStore在公共目录下读写文件
访问或者共享非媒体文件,使用系统的文件选择器SAF在公共目录Download下读写文件。
根目录下可以创建自定义文件夹、文件。
升级 targetSdkVersion
- android
- defaultConfig {
- targetSdkVersion 30
- }
- }
添加清单权限
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
代码动态申请
- public final class PermissionActivity extends AppCompatActivity {
-
- private static final int REQUEST_CODE = 1024;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestPermission();
- }
-
- private void requestPermission() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- // 先判断有没有权限
- if (Environment.isExternalStorageManager()) {
- writeFile();
- } else {
- Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
- intent.setData(Uri.parse("package:" + context.getPackageName()));
- startActivityForResult(intent, REQUEST_CODE);
- }
- } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- // 先判断有没有权限
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
- ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
- writeFile();
- } else {
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
- }
- } else {
- writeFile();
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == REQUEST_CODE) {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
- ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
- writeFile();
- } else {
- ToastUtils.show("存储权限获取失败");
- }
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_CODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- if (Environment.isExternalStorageManager()) {
- writeFile();
- } else {
- ToastUtils.show("存储权限获取失败");
- }
- }
- }
-
- /**
- * 模拟文件写入
- */
- private void writeFile() {
- ToastUtils.show("写入文件成功");
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。