
注意: 本篇文章讲述的是外部存储。首先“Android 官方文档中”外部存储就是目前我们手机上能看到的【手机存储空间】。很久之前手机内存不足是需要插入SD卡的所以是外部存储空间。由于历史遗留原因 后面就没有改回。下图是文章总结1. 了解Android 存储分类这里要搞清楚SD卡只是外部存储的一种。网址2.了解 应用目录 和 共享目录的 概念。Android 会在存储卡的 Android/data 目录下给每个应用单独建立一个文件目录称为应用目录只有应用自己可以访问此目录会随着应用卸载删除。共享目录所有应用均可访问的空间/storage/emulated/0/下的公共文件夹。/* 获取当前应用目录 下的 Download路径 */ String path getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(); /* 获取当前APP 缓存目录 */ getExternalCacheDir() /* 获取公共共享目录 下的 Download路径 */ String path Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();3. Android 外部存储访问权限变化过程Android 4.4Android 4.4 之前 随意访问外部存储。从Android 4.4 开始只能访问自身应用目录如需访问外部存储其它空间需要在 AndroidManifest.xml 中声明申请如下权限。!-- 访问外部存储中应用目录之外的任何文件, Android 13 废弃 -- uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/ !-- 向应用目录以外的任何文件写入数据 Android 13 废弃 -- uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/Android 6.0从Android 6.0 开始系统将部分权限归类为“危险权限”如摄像头、定位、存储等这些危险权限需要请求权限步骤如下1. 检查 APP 是否开启了指定权限ContextCompat.checkSelfPermission(Context, permission)判断指定权限是否开启。/* 1. 定义String 数组 存储要申请的权限 */ private String[] permissions_10 new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; private void request() { /* android 6.0 开始 自己请求运行时权限 */ /* 1.2 定义 List 列表存储未授权的权限 */ ListString permissionList new ArrayList(); if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { /* Android 10和之前 只需要申请如下两项权限 Android 13. 这两项权限废弃 */ for (String permisssion: permissions_10) { if (ContextCompat.checkSelfPermission(this, permisssion) ! PackageManager.PERMISSION_GRANTED) { permissionList.add(permisssion); } } }2. 请求系统弹窗供用户选择是否开启权限ActivityCompat.requestPermissions(Activity, String[] permissions, int requestCode)申请指定的权限/* 2. 申请 未授权 的权限 */ if (!permissionList.isEmpty()) { ActivityCompat.requestPermissions(this, permissionList.toArray(new String[0]), 17); }3. 判断用户的权限选择结果重写 onRequestPermissionsResult() 方法判断结果public void onRequestPermissionsResult(int requestCode, NonNull String[] permissions, NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // requestCode不能为负数也不能大于2的16次方即65536 if (requestCode 17) { boolean allGranted true; for (int result: grantResults) { if (result ! PackageManager.PERMISSION_GRANTED) { // 判断权限是否授权成功 allGranted false; break; } } if (allGranted) { // 权限全部授权成功 } else { Toast.makeText(this, 部分功能被拒绝功能可能无法正常使用, Toast.LENGTH_SHORT).show(); } } }Android 7.0不能使用 真实路径file://需要使用content://URI路径对象。将字符串格式的文件路径转为 Uri 对象Uri.parse(String file_path)。Android 10Android 10.0 开始Android 外部存储 开始实行作用域存储分区存储即分为只有应用自己可以访问的私有应用目录和 所有应用均可访问的共享公共目录。默认可访问自身应用目录和自身应用创建的媒体文件使用MediaStore方法。访问外部存储的其它文件除其他私有应用目录最简单方式——暂时停用作用域存储并声明请求之前那两个权限在 AndoridManifest.xml 的 application 节点声明如下manifest ... uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/ !-- 向应用专属目录以外的任何文件写入数据 Android 13 废弃 -- uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/ !-- 暂时停用分区存储 Android 11 失效 -- application android:requestLegacyExternalStoragetrue ... /application /manifestAndroid 11与Android 10 还可以停用分区存储不同Android 11 开始强制执行分区存储机制。分区存储机制应用只能访问自己的应用目录无法访问属于其他应用的应用专属目录。访问权限不变写入权限改变。访问除应用专属目录和 MediaStore 之外文件的写入权限在 AndroidManifest.xml 声明如下权限并请求该权限。!-- Android 11 引入, 拥有除应用专属目录和 MediaStore 之外文件的写入权限 -- uses-permission android:nameandroid.permission.MANAGE_EXTERNAL_STORAGE/if (Build.VERSION.SDK_INT Build.VERSION_CODES.R) { /* Android 11. 需申请 MANAGE_EXTERNAL_STORAGE */ if (!Environment.isExternalStorageManager()) { /** 判断当前应用是否拥有 所有文件访问权限 **/ // 注意特殊权限 需要通过 Intent 引导用户前往设置页开启 Intent intent new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); intent.setData(Uri.parse(package:getPackageName())); startActivity(intent); } }Android 13Android 13 开始 访问权限不变媒体权限细化 导致 申请权限改变。Android 媒体权限细化之前的那两个权限废弃新的申请权限如下如果你们发现有什么问题可以评论区提出。感谢