1. 前言
希望存储文件在外部存储目录,但是在Android中现在Environment.getExternalStorageDirectory()
获取外部存储根目录的方法已经过时,而推荐使用的是:
context.getExternalFilesDir(null)
这个文件目录位于外部SD卡的应用目录中,比如下图:
但是很明显这个还是应用的私有目录,随着应用的卸载会被删除。所以这里其实不是自己所期望的。孤儿尝试用另一种方式来解决这个问题。
2. 解决
在测试的时候,可以打印一下目录:
context.getExternalFilesDir(null).getAbsolutePath();
结果:
/storage/emulated/0/Android/data/com.weizu.downloader/files
所以其实可以向上层一直搜索,比如下面的代码:
// 调用
File sdCardRoot = findSDCardRoot(context.getExternalFilesDir(null));
File directory = new File(sdCardRoot.toString() + File.separator + cacheDir);
// 申明
private static File findSDCardRoot(File externalFilesDir) {
File parent;
boolean equals = (Objects.requireNonNull(parent = externalFilesDir.getParentFile())).getName().equals("0");
if (!equals) {
return findSDCardRoot(parent);
} else {
return parent;
}
}
最终得到的目录为:
/storage/emulated/0/wfiledownload/
但是在Android 10
及其以后写入外部存储更加严格:
WRITE_EXTERNAL_STORAGE no longer provides write access when targeting Android 10+
可以在AndroidManifest.xml
文件中的application
标签中配置:
android:requestLegacyExternalStorage="true"
配置了之后,不要忘记了动态权限申请:
// 请求读写权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
然后就会顺利弹窗让用户授权。就可以进行外部目录的创建了。
// 目录不存在就创建
if (!directory.exists()) {
LogUtil.e(directory.getAbsolutePath()+" 目录不存在");
boolean mkdirs = directory.mkdirs();
LogUtil.e("创建" + (mkdirs ? "成功" : "失败"));
}
但是,最终在手机上测试发现并没有将文件写入到我的外部SD
卡,而是自带的64G
的存储空间中。猜测可能现在手机的提供的64G
、128G
等其实就是第一个外部存储SD
卡。