软件编程
位置:首页>> 软件编程>> Android编程>> Android11及以上文件读写权限申请详细介绍

Android11及以上文件读写权限申请详细介绍

作者:有点料  发布时间:2022-04-14 01:02:42 

标签:android11,读写,权限

Android11 读写权限申请

Android11系统对应用写入权限做了严格的限制。本文介绍如何获取文件读写权限。项目中 build.gradle 的targetSdkVersion >= 29 ,会出现读写问题。

targetSdkVersion = 29,通过设置requestLegacyExternalStorage=“true”,还能解决。

targetSdkVersion = 30后,需要申请所有文件权限才能获取到写入权限。

AndroidManifest添加权限设置

<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;
           }
       }
   }

Android11申请权限

跳转系统设置界面,用户授权获取权限。

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;
           // 授权失败
       }
   }
}

Android11及以上文件读写权限申请详细介绍

对于部分手机如小米手机,即使获取了所有文件的管理权限,依旧访问不到Android/data目录,如图:

Android11及以上文件读写权限申请详细介绍

尝试解决办法:

只在外部存储的应用私有目录下,用直接路径读写文件。

访问或者共享媒体文件,使用MediaStore在公共目录下读写文件

访问或者共享非媒体文件,使用系统的文件选择器SAF在公共目录Download下读写文件。

根目录下可以创建自定义文件夹、文件。

补充:Android 11 及以上申请外部存储权限

升级 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("写入文件成功");
   }
}

来源:https://blog.csdn.net/yzwfeng/article/details/124378291

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com