Android App专属文件(app-specific files)存储

文章介绍了Android中App如何访问和管理专属的内部存储与外部存储目录,包括用于持久化文件和缓存文件的路径,以及如何在不同Android版本下进行操作。内部存储在App卸载时会被删除,外部存储则提供了跨App的共享可能性。Android10及更高版本引入了作用域存储模式,限制了对外部存储的访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

有很多场景,我们的App需要创建一些其他App不需要访问、不应该访问的文件,系统提供了一下两种App专属(app-specific)存储目录:

1、内部存储目录(Internal storage directories):

指的是:/data/user/0/packagename/…目录
该目录提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录其他App无法访问。

2、外部存储目录(External storage directories):

指的是:/storage/emulated/0/Android/data/packagename/…目录
该目录也提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录旨在存储本应用使用的文件,如果需要存储一些可供其他应用访问的共享文件,请使用可共享存储技术(Media content、Documents and other files、Datasets)

App专属存储目录,随着App卸载,会被删除。

一、访问内部存储(Access From Internal Storage)

注意:这个目录往往比较小。内部存储(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.

1、getFilesDir:访问持久化文件(Access persistent files)

指的是:/data/user/0/packagename/files/…目录

1.1、访问和存储文件(context.getFilesDir())

File file = new File(context.getFilesDir(), filename);

1.2、使用流存储文件(context.openFileOutput())

文件会存储到getFileDir()目录下

String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
    fos.write(fileContents.toByteArray());
}

1.3、使用流访问文件(context.openFileInput())

访问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();
}

1.4、查看文件列表(context.fileList())

查看getFileDir()目录下的所有文件

Array<String> files = context.fileList();

2、getCacheDir:创建缓存文件(Create cache files)

指的是:/data/user/0/packagename/cache/…目录

File.createTempFile(filename, null, context.getCacheDir());
File cacheFile = new File(context.getCacheDir(), filename);

二、访问外部存储(Access From External Storage)

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.

1、getExternalFilesDir:访问持久化文件(Access persistent files)

指的是:/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.

2、getExternalCacheDir:创建缓存文件(Create cache files)

指的是:/storage/emulated/0/Android/data/packagename/cache/…目录

File externalCacheFile = new File(context.getExternalCacheDir(), filename);

3、Environment.getExternalStorageState:检查外部存储是否可用

// 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);
}
### Android Build System `PRODUCT_OUT/vendor/priv-app` Directory Purpose and Usage The variable `$(PRODUCT_OUT)` represents the root output directory where all built files are placed during an Android build process. This includes images, compiled applications, libraries, etc.[^1] For the specific path `$(PRODUCT_OUT)/vendor/priv-app`, this location serves a specialized role within the file structure: - **Vendor Partition**: The `/vendor` part of the path indicates that these components belong to what is known as the vendor partition in newer versions of Android (A/B update systems). Vendor partitions separate hardware-specific proprietary code from the rest of the system image. - **Privileged Applications**: The term `priv-app` refers to privileged applications which have elevated permissions beyond those granted to regular apps installed by users or even through standard methods like Google Play Store. These applications typically come pre-installed on devices and can perform actions not available to ordinary user-space programs due to their deeper integration with core OS features and services. To illustrate how such paths might be used in practice when configuring builds via Makefiles (`*.mk`) consider following snippet demonstrating inclusion rules for placing APKs into appropriate directories at compile time: ```makefile # Example configuration for including a debug version of Contacts app under priv-app LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := com.amazon.dp.contacts.apk LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_SUFFIX := .apk LOCAL_CERTIFICATE := PRESIGNED LOCAL_PRIVILEGED_MODULE := true LOCAL_OVERRIDES_PACKAGES += Contacts LOCAL_DEX_PREOPT := false include $(BUILD_PREBUILT) # Ensure final placement inside /vendor/priv-app/ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/com.amazon.dp.contacts.apk:$(TARGET_COPY_OUT_VENDOR)/priv-app/Contacts
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值