Bootstrap

Android各个版本存储权限适配

一、Android6.0-9.0

        1、动态权限申请:

private static String[] arrPermissions ={
            android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.CAMERA
    };

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            lstUnPermissions.clear();
            for(int i =0; i< arrPermissions.length; i++){
                if(ActivityCompat.checkSelfPermission(this, arrPermissions[i])!= PackageManager.PERMISSION_GRANTED){
                    lstUnPermissions.add(arrPermissions[i]);
                }
            }
            if(lstUnPermissions.size() >0 ){
                ActivityCompat.requestPermissions(this, arrPermissions, Request_Permission_Code);
            }
            else{
                //已经全部拥有权限
                Log.e("权限状态:", "已经全部拥有权限,无需动态申请");
                hasPermission_array = true;
            }
        }

        2、权限回调

//权限请求回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case Request_Permission_Code:
                hasPermission_array = true;
                for(int i=0;i<grantResults.length;i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        hasPermission_array = false;
                        showPermissionSettingDialog_new();

                    }
                }
                break;
            default:
                break;
        }
    }

        3、拒绝权限时跳转详细设置页面

private void showPermissionSettingDialog_new(){
        ColorDialog.OnPositiveListener btnGoPermission = new ColorDialog.OnPositiveListener() {
            @Override
            public void onClick(ColorDialog dialog) {
                dialog.dismiss();
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            }
        };
        ColorDialog dialogPermission = WinShow.WinShowColorOperator(this, "权限申请", "请前往设置页面授予所有权限以继续使用",
                -1, btnGoPermission, "去设置");
        dialogPermission.getWindow().setGravity(Gravity.CENTER);
    }

二、Android10.0

        虽然 Android10 上面提出了外部存储分区的概念,不过之前的版本中,我们只要为应用添加了 android:requestLegacyExternalStorage="true" 就可以像之前的方式一样访问手机的外部存储空间。

        

三、Android11 及以上

        1、AndroidManifest添加权限设置

<!-- Android11额外添加 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

        2、请求所有文件管理权限

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
            if (!android.os.Environment.isExternalStorageManager()) {
                hasPermission_files = false;
                ColorDialog.OnPositiveListener btnGoPermission = new ColorDialog.OnPositiveListener() {
                    @Override
                    public void onClick(ColorDialog dialog) {
                        dialog.dismiss();
                        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                        intent.setData(Uri.parse("package:" + getPackageName()));
                        startActivityForResult(intent, Request_Manage_Files_Code);
                    }
                };
                ColorDialog dialogPermission = WinShow.WinShowColorOperator(this, "必要权限未开启", "此应用程序需要获取“访问所有文件”权限," +
                        "才可以正常使用!请开启相关权限。", -1, btnGoPermission, "去设置");
                dialogPermission.getWindow().setGravity(Gravity.BOTTOM);
            }
            else{
                hasPermission_files = true;
            }
        }

       3、权限回调

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            switch (requestCode) {
                case Request_Manage_Files_Code:
                    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R) {
                        if (!android.os.Environment.isExternalStorageManager()) {
                            hasPermission_files = false;
                            WinShow.WinShowColor(this, "无法继续", "请先开启所有文件管理权限!", WinShow.ColorDialogType.错误);
                        }
                        else{
                            hasPermission_files = true;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        catch (Exception ex){
            Log.e("欢迎页面回调错误",ex.getMessage());
            StackTraceElement[] arrErrStack=ex.getStackTrace();
            for(int i=0;i<arrErrStack.length;i++) {
                Log.e("欢迎页面回调错误:",arrErrStack[i].toString() );
            }
        }
    }

        参考链接:

Android 11新特性,Scoped Storage又有了新花样

Android 11 上的文件读写权限(MANAGE_EXTERNAL_STORAGE)_android 读写权限-CSDN博客

Android存储权限完美适配(Android11及以上适配)_android 11 适配-CSDN博客

安卓权限动态申请,永久禁止后跳转到权限设置页面监听回调_如何设置权限的监听回调-CSDN博客

Android 动态权限申请及回调_android 动态权限申请回调-CSDN博客

android 权限管理之判断禁止后不再提示_permision.requestandroidpermission如何关闭弹窗提示-CSDN博客

android11 权限拒绝后如何重新弹窗_mob64ca12ebb57f的技术博客_51CTO博客

Android13适配所有文件管理权限_pictureselector 安卓13-CSDN博客

Android CameraX适配Android13的踩坑之路-CSDN博客

记一个 Android 14 适配引发的Android 存储权限问题-CSDN博客

Android 11及以上授予文件管理权限-云社区-华为云

 解决Android ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION的具体操作步骤_mob649e81607bf3的技术博客_51CTO博客

实战 Android 升级目标版本到 30 过程中遇到的问题及解决办法

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;