Android所有版本的存储权限适配

             第一步:在Manifest文件添加如下权限
         <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" tools:ignore="ScopedStorage"/>
             <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
         <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

         android:requestLegacyExternalStorage="true"
         第二步:定义以下常量
         private static final int REQUEST_CODE_FOR_READ_MEDIA_IMAGES_PERMISSION_FROM_ANDROID_13 = 0x00000003;
             private static final int REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12 = 0x00000005;
             private static final int REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_ANDROID_6_TO_ANDROID_9 = 0x00000006;
         第三步:在需要写入文件的地方编写以下代码
            java.io.OutputStream outputStream = null;
            java.lang.String errorMessage = "";
            java.lang.String fileName = "test_导出资料_" + java.lang.System.currentTimeMillis() + ".xls";
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                android.util.Log.d("debug", "设备系统的版本号是大于等于安卓6.0以上的版本,需要检查运行时的危险权限");
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                    android.util.Log.d("debug", "设备系统的版本号是大于等于安卓10.0以上的版本,说明是只能用媒介存储写入文件和读取文件");
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
                        android.util.Log.d("debug", "设备系统的版本号是大于等于安卓13.0以上的版本,换成检查Media声音和Media视频和Media图片的权限");
                        int checkSelfPermissionResultForReadMediaImages = checkSelfPermission(android.Manifest.permission.READ_MEDIA_IMAGES);
                        android.util.Log.d("debug", "checkSelfPermissionResultForReadMediaImages->" + checkSelfPermissionResultForReadMediaImages);
                        if (checkSelfPermissionResultForReadMediaImages == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                            android.util.Log.d("debug", "已经授予媒介图片的读取权限");
                            android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                            android.content.ContentValues contentValues = new android.content.ContentValues();
                            contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                            contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                            android.content.ContentResolver contentResolver = getContentResolver();
                            android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                            try {
                                outputStream = contentResolver.openOutputStream(uriForInsertResult);
                            } catch (java.io.IOException ioException) {
                                ioException.printStackTrace();
                                errorMessage = ioException.getMessage();
                            }
                        } else {
                            errorMessage = "需要授予权限";
                            android.util.Log.d("debug", "没有授予媒介图片的读取权限");
                            android.util.Log.d("debug", "现在执行请求读取媒介图片的权限");
                            java.lang.String[] permission = new java.lang.String[1];
                            permission[0] = android.Manifest.permission.READ_MEDIA_IMAGES;
                            requestPermissions(permission, REQUEST_CODE_FOR_READ_MEDIA_IMAGES_PERMISSION_FROM_ANDROID_13);
                        }
                        int checkSelfPermissionResultForReadExternalStorage = checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE);
                        int checkSelfPermissionResultForWriteExternalStorage = checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
                        android.util.Log.d("debug", "检测完读取媒介图片权限之后再检测外部存储读取权限看看->" + checkSelfPermissionResultForReadExternalStorage);
                        android.util.Log.d("debug", "检测完读取媒介图片权限之后再检测外部存储写入权限看看->" + checkSelfPermissionResultForWriteExternalStorage);
                    } else {
                        android.util.Log.d("debug", "设备系统的版本号时介于10.0到12.0之间的,通过android.provider.MediaStore获取外部存储目录");
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
                            android.util.Log.d("debug", "安卓11或者安卓12通过Environment的isExternalStorageManager方法检查是否有权限");
                            if (android.os.Environment.isExternalStorageManager()) {
                                android.util.Log.d("debug", "在安卓11或者安卓12中有读写文件的权限");
                                android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                                android.content.ContentValues contentValues = new android.content.ContentValues();
                                contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                                contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                                android.content.ContentResolver contentResolver = getContentResolver();
                                android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                                try {
                                    outputStream = contentResolver.openOutputStream(uriForInsertResult);
                                } catch (java.io.IOException ioException) {
                                    ioException.printStackTrace();
                                    errorMessage = ioException.getMessage();
                                }
                            } else {
                                errorMessage = "需要授予权限";
                                android.util.Log.d("debug", "安卓11或者安卓12的逻辑请求权限");
                                try {
                                    Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                                    intent.addCategory("android.intent.category.DEFAULT");
                                    intent.setData(android.net.Uri.parse(String.format("package:%s",getApplicationContext().getPackageName())));
                                    startActivityForResult(intent, REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    Intent intent = new Intent();
                                    intent.setAction(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                                    startActivityForResult(intent, REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12);
                                }
                            }
                        } else {
                            android.util.Log.d("debug", "在安卓10版本中沿用之前的检查方法");
                            int checkSelfPermissionResultForReadExternalStorage = androidx.core.app.ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE);
                            //int checkSelfPermissionResultForWriteExternalStorage = androidx.core.app.ActivityCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
                            android.util.Log.d("debug", "checkSelfPermissionResultForReadExternalStorage->" + checkSelfPermissionResultForReadExternalStorage);
                            //android.util.Log.d("debug", "checkSelfPermissionResultForWriteExternalStorage->" + checkSelfPermissionResultForWriteExternalStorage);
                            //boolean isHavePermission = checkSelfPermissionResultForReadExternalStorage == android.content.pm.PackageManager.PERMISSION_GRANTED && checkSelfPermissionResultForWriteExternalStorage == android.content.pm.PackageManager.PERMISSION_GRANTED;
                            if (checkSelfPermissionResultForReadExternalStorage == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                                android.util.Log.d("debug", "已经授予外部存储写入权限");
                                android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                                android.content.ContentValues contentValues = new android.content.ContentValues();
                                contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                                contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                                android.content.ContentResolver contentResolver = getContentResolver();
                                android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                                try {
                                    outputStream = contentResolver.openOutputStream(uriForInsertResult);
                                } catch (java.io.IOException ioException) {
                                    ioException.printStackTrace();
                                    errorMessage = ioException.getMessage();
                                }
                            } else {
                                errorMessage = "需要授予权限";
                                android.util.Log.d("debug", "没有授予外部存储写入权限");
                                android.util.Log.d("debug", "现在执行请求外部存储写入的权限");
                                android.util.Log.d("debug", "安卓10的逻辑请求权限");
                                java.lang.String[] permission = new java.lang.String[2];
                                permission[0] = android.Manifest.permission.READ_EXTERNAL_STORAGE;
                                permission[1] = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
                                requestPermissions(permission, REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12);
                            }
                        }
                    }
                } else {
                    android.util.Log.d("debug", "设备系统的版本号是介于6.0到9.0之间,仍然是可以从Environment类的getExternalStorageDirectory方法获取外部存储目录的,但是前提是要检查运行时权限");
                    int checkSelfPermissionResultForWriteExternalStorage = checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
                    if (checkSelfPermissionResultForWriteExternalStorage == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                        java.io.File externalStorageDirectory = android.os.Environment.getExternalStorageDirectory();
                        android.util.Log.d("debug", "安卓系统是在6.0到9.0之间的,通过Environment类获取到外部存储目录->" + externalStorageDirectory.getPath());
                        try {
                            outputStream = new java.io.FileOutputStream(externalStorageDirectory.getPath() + java.io.File.separator + fileName);
                        } catch (java.io.IOException ioException) {
                            ioException.printStackTrace();
                            errorMessage = ioException.getMessage();
                        }
                    } else {
                        errorMessage = "需要授予权限";
                        java.lang.String[] permission = new java.lang.String[1];
                        permission[0] = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
                        requestPermissions(permission, REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_ANDROID_6_TO_ANDROID_9);
                    }
                }
            } else {
                android.util.Log.d("debug", "设备系统的版本号小于6.0以下的版本,不需要检查运行时权限");
                java.io.File externalStorageDirectory = android.os.Environment.getExternalStorageDirectory();
                android.util.Log.d("debug", "直接通过Environment类的getExternalStorageDirectory()即可获取外部存储目录->" + externalStorageDirectory.getPath());
                try {
                    outputStream = new java.io.FileOutputStream(externalStorageDirectory.getPath() + java.io.File.separator + fileName);
                } catch (java.io.IOException ioException) {
                    ioException.printStackTrace();
                    errorMessage = ioException.getMessage();
                }
            }
            if (outputStream != null) {
                //file write
            } else {
                android.widget.Toast.makeText(this, errorMessage, android.widget.Toast.LENGTH_LONG).show();
            }


        第四步:权限请求回调函数
        @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_FOR_READ_MEDIA_IMAGES_PERMISSION_FROM_ANDROID_13) {
            if (grantResults.length > 0 && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                if (permissions.length > 0) {
                    android.util.Log.d("debug", "打印授予的权限->" + permissions[0]);
                }
                java.lang.String fileName = "buyup_导出资料_" + java.lang.System.currentTimeMillis() + ".xls";
                java.lang.String errorMessage = "";
                java.io.OutputStream outputStream = null;
                android.util.Log.d("debug", "设备系统的版本号是大于等于安卓10.0以上的版本,说明是只能用媒介存储写入文件和读取文件");
                android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                android.content.ContentValues contentValues = new android.content.ContentValues();
                contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                android.content.ContentResolver contentResolver = getContentResolver();
                android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                try {
                    outputStream = contentResolver.openOutputStream(uriForInsertResult);
                } catch (java.io.IOException ioException) {
                    ioException.printStackTrace();
                    errorMessage = ioException.getMessage();
                }
                if (outputStream != null) {
                    //file write
                } else {
                    android.widget.Toast.makeText(this, errorMessage, android.widget.Toast.LENGTH_LONG).show();
                }
            } else {
                if (permissions.length > 0) {
                    java.lang.String permission0 = permissions[0];
                    android.util.Log.d("debug", "打印请求的权限->" + permission0);
                }
                android.util.Log.d("debug", "权限授予失败");
                android.widget.Toast.makeText(this, "权限授予失败", android.widget.Toast.LENGTH_LONG).show();
            }
        } else if (requestCode == REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FOR_ANDROID_6_TO_ANDROID_9) {
            if (grantResults.length > 0 && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                if (permissions.length > 0) {
                    android.util.Log.d("debug", "来自安卓6.0到安卓9.9之间的请求权限,打印授予的权限->" + permissions[0]);
                }
                java.lang.String fileName = "buyup_导出资料_" + java.lang.System.currentTimeMillis() + ".xls";
                java.lang.String errorMessage = "";
                java.io.OutputStream outputStream = null;
                android.util.Log.d("debug", "设备系统的版本号是大于等于安卓6.0到安卓9.0之间的,通过用android.os.Environment类获取外部存储");
                java.io.File externalStorageDirectory = android.os.Environment.getExternalStorageDirectory();
                try {
                    outputStream = new java.io.FileOutputStream(externalStorageDirectory.getPath() + java.io.File.separator + fileName);
                } catch (java.io.IOException ioException) {
                    ioException.printStackTrace();
                    errorMessage = ioException.getMessage();
                }
                if (outputStream != null) {
                    //file write
                } else {
                    android.widget.Toast.makeText(this, errorMessage, android.widget.Toast.LENGTH_LONG).show();
                }
            } else {
                if (permissions.length > 0) {
                    android.util.Log.d("debug", "来自安卓6.0到安卓9.9之间的请求权限,打印拒绝的权限->" + permissions[0]);
                }
                android.util.Log.d("debug", "来自安卓6.0到安卓9.9之间的请求权限,权限授予失败");
                android.widget.Toast.makeText(this, "权限授予失败", android.widget.Toast.LENGTH_LONG).show();
            }
        } else if (requestCode == REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12) {
            if (grantResults.length > 0 && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                if (permissions.length > 0) {
                    android.util.Log.d("debug", "来自安卓10.0的版本,打印授予的权限->" + permissions[0]);
                    android.util.Log.d("debug", "来自安卓10.0的版本,打印授予的权限->" + permissions[1]);
                }
                java.lang.String fileName = "buyup_导出资料_" + java.lang.System.currentTimeMillis() + ".xls";
                java.lang.String errorMessage = "";
                java.io.OutputStream outputStream = null;
                android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                android.content.ContentValues contentValues = new android.content.ContentValues();
                contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                android.content.ContentResolver contentResolver = getContentResolver();
                android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                try {
                    outputStream = contentResolver.openOutputStream(uriForInsertResult);
                } catch (java.io.IOException ioException) {
                    ioException.printStackTrace();
                    errorMessage = ioException.getMessage();
                }
                if (outputStream != null) {
                    //file write
                } else {
                    android.widget.Toast.makeText(this, errorMessage, android.widget.Toast.LENGTH_LONG).show();
                }
            } else {
                if (permissions.length > 0) {
                    android.util.Log.d("debug", "来自安卓10.0的版本,打印拒绝的权限->" + permissions[0]);
                    android.util.Log.d("debug", "来自安卓10.0的版本,打印拒绝的权限->" + permissions[1]);
                }
                android.widget.Toast.makeText(this, "权限授予失败", android.widget.Toast.LENGTH_LONG).show();
            }
        }
    }


    第五步:针对安卓11或者安卓12版本的请求权限方法
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_FOR_WRITE_EXTERNAL_STORAGE_PERMISSION_FROM_ANDROID_10_TO_ANDROID_12) {
            android.util.Log.d("debug", "在安卓11或者安卓12系统中引导到系统设置界面开启权限回来");
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
                if (android.os.Environment.isExternalStorageManager()) {
                    android.util.Log.d("debug", "已经授予外部存储写入权限");
                    java.io.OutputStream outputStream = null;
                    java.lang.String errorMessage = "";
                    java.lang.String fileName = "buyup_导出资料_" + java.lang.System.currentTimeMillis() + ".xls";
                    android.util.Log.d("debug", "设备系统的版本号时介于10.0到12.0之间的,通过android.provider.MediaStore获取外部存储目录");
                    android.net.Uri uri = android.provider.MediaStore.Files.getContentUri("external");
                    android.content.ContentValues contentValues = new android.content.ContentValues();
                    contentValues.put(android.provider.MediaStore.MediaColumns.DISPLAY_NAME, fileName);
                    contentValues.put(android.provider.MediaStore.MediaColumns.MIME_TYPE, "application/x-xls");
                    android.content.ContentResolver contentResolver = getContentResolver();
                    android.net.Uri uriForInsertResult = contentResolver.insert(uri, contentValues);
                    try {
                        outputStream = contentResolver.openOutputStream(uriForInsertResult);
                    } catch (java.io.IOException ioException) {
                        ioException.printStackTrace();
                        errorMessage = ioException.getMessage();
                    }
                    if (outputStream != null) {
                        //file write
                    } else {
                        android.widget.Toast.makeText(this, errorMessage, android.widget.Toast.LENGTH_LONG).show();
                    }
                } else {
                    android.widget.Toast.makeText(this, "需要授予权限才能导出文件!", android.widget.Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

相关推荐

  1. Android所有版本存储权限

    2024-01-13 06:32:02       23 阅读
  2. Android 10 】隐私权限变更

    2024-01-13 06:32:02       33 阅读
  3. android11以上SD卡存储权限申请问题

    2024-01-13 06:32:02       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-13 06:32:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-13 06:32:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-13 06:32:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-13 06:32:02       20 阅读

热门阅读

  1. Ubuntu上使用Snap安装Docker

    2024-01-13 06:32:02       42 阅读
  2. 系统语言德语时浮点数转化问题

    2024-01-13 06:32:02       36 阅读
  3. MongoDB聚合:$documents

    2024-01-13 06:32:02       36 阅读
  4. TIDB的忘了root用户密码和数据库密码解决办法

    2024-01-13 06:32:02       22 阅读
  5. 编程笔记 html5&css&js 036 CSS概述

    2024-01-13 06:32:02       27 阅读
  6. 【Elasticsearch】Elasticsearch集群搭建详细手册

    2024-01-13 06:32:02       39 阅读
  7. 给el-select的change事件传自己想要的参数

    2024-01-13 06:32:02       30 阅读
  8. Ubuntu按转发HDF5

    2024-01-13 06:32:02       35 阅读
  9. python类装饰器编写单体类

    2024-01-13 06:32:02       34 阅读
  10. 第一天业务题

    2024-01-13 06:32:02       35 阅读
  11. pytest框架

    2024-01-13 06:32:02       30 阅读
  12. 《设计模式的艺术》笔记 - 工厂方法模式

    2024-01-13 06:32:02       32 阅读
  13. Python pytest入门教程

    2024-01-13 06:32:02       34 阅读