最近刚买了个Android12 手机,这日饶有兴致的把项目装在手机上装个小B,谁曾想在下载视频时无法下载导致视频播放不了,然后再拿测试机和Pad都试了试没啥问题啊,这是为何,清单文件里面也配置了不启动分区了,首先猜想是文件夹创建失败了,赶紧把log输出出来,眼巴巴的看到了文件创建失败的log,尴尬的笑了……
Android 10 改变了文件的存储方式不允许应用随意创建文件夹了,要用安卓提供的文件夹,当APP卸载时创建的文件夹一并会删除,避免在根目录下创建的文件不会随着APP卸载而删除,这就导致了垃圾数据,占用手机内存,Google是不允许这么做的;
在Android 11版本上,系统会根据App targetSdkVersion决定运行模式:
●? App targetSdkVersion < 29,默认为分区存储,可通过requestLegacyExternalStorage更改
应用可以通过AndroidManifest.xml设置requestLegacyExternalStorage, 选择对应的方式:
●? App targetSdkVersion < 29,声明了READ_EXTERNAL_STORAGE,默认Legacy Mode
●? App targetSdkVersion >= 30,默认为分区存储,并且无法取消。
●? App在下列条件都成立时
■? 声明 MANAGE_EXTERNAL_STORAGE 权限。
■? 使用 ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION intent 操作将用户引导至一个系统设置页面,在该页面上,用户可以为您的应用启用以下选项:授予所有文件的管理权限。
App拥有外置存储空间Read、Write权限。但是通过Environment.isExternalStorageLegacy接口判断,返回不一定是Legacy Mode。
判断当前App运行什么模式,可以通过这个API判断:
Environment.isExternalStorageLegacy() (api 29);
public static String getSDPath(Context context) {
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);// 判断sd卡是否存在
if (sdCardExist) {
if (Build.VERSION.SDK_INT >= 29) {
//Android10之后
sdDir = context.getExternalFilesDir(null);//获取应用所在根目录/Android/data/your.app.name/file/ 也可以根据沙盒机制传入自己想传的参数,存放在指定目录
} else {
sdDir = Environment.getExternalStorageDirectory();// 获取SD卡根目录
}
} else {
sdDir = Environment.getRootDirectory();// 获取跟目录
}
return sdDir.toString();
}
|