有很多场景,我们的App需要创建一些其他App不需要访问、不应该访问的文件,系统提供了一下两种App专属(app-specific)存储目录:
指的是:/data/user/0/packagename/…目录
该目录提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录其他App无法访问。
指的是:/storage/emulated/0/Android/data/packagename/…目录
该目录也提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录旨在存储本应用使用的文件,如果需要存储一些可供其他应用访问的共享文件,请使用可共享存储技术(Media content、Documents and other files、Datasets)
App专属存储目录,随着App卸载,会被删除。
注意:这个目录往往比较小。内部存储(Internal storage)只提供有限的空间给App专属数据。
Keep in mind, however, that these directories tend to be small. Before writing app-specific files to internal storage, your app should query the free space on the device.
How much space does your data require?
Internal storage has limited space for app-specific data. Use other types of storage if you need to save a substantial amount of data.
指的是:/data/user/0/packagename/files/…目录
File file = new File(context.getFilesDir(), filename);
文件会存储到getFileDir()目录下
String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
fos.write(fileContents.toByteArray());
}
访问getFileDir()目录下的文件
FileInputStream fis = context.openFileInput(filename);
InputStreamReader inputStreamReader =
new InputStreamReader(fis, StandardCharsets.UTF_8);
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
String line = reader.readLine();
while (line != null) {
stringBuilder.append(line).append('\n');
line = reader.readLine();
}
} catch (IOException e) {
// Error occurred when opening raw file for reading.
} finally {
String contents = stringBuilder.toString();
}
查看getFileDir()目录下的所有文件
Array<String> files = context.fileList();
指的是:/data/user/0/packagename/cache/…目录
File.createTempFile(filename, null, context.getCacheDir());
File cacheFile = new File(context.getCacheDir(), filename);
Android 4.4及以后,App不再需要请求存储权限就可以访问外部存储中的App专属目录
Android 10(API level 29) 及以后,App默认开启作用域存储模式,App将不能访问非当前应用专属的路径。
只能访问外部存储上当前App专属路径,和App已经创建的指定媒体类型(MediaStore APIs)
On Android 4.4 (API level 19) or higher, your app doesn’t need to request any storage-related permissions to access app-specific directories within external storage. The files stored in these directories are removed when your app is uninstalled.
Scoped storage
To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or scoped storage, by default. Such apps have access only to the app-specific directory on external storage, as well as specific types of media that the app has created.
指的是:/storage/emulated/0/Android/data/packagename/files/…目录
File appSpecificExternalDir = new File(context.getExternalFilesDir(null), filename);
pass null into getExternalFilesDir(). This returns the root app-specific directory within external storage.
指的是:/storage/emulated/0/Android/data/packagename/cache/…目录
File externalCacheFile = new File(context.getExternalCacheDir(), filename);
// Checks if a volume containing external storage is available
// for read and write.
private boolean isExternalStorageWritable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
// Checks if a volume containing external storage is available to at least read.
private boolean isExternalStorageReadable() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ||
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
}