Android中实现跨应用无UI访问内部存储文件的方案咨询(替代API 29已废弃的同userId共享机制)
跨应用无UI文件共享 + 外部存储加密方案
嘿,我正好碰过类似的需求,给你分享几个靠谱的方案:
一、无UI交互实现App2访问App1文件
废弃同userId之后,FileProvider是官方推荐的无UI跨应用文件共享方式,完全匹配你的需求,具体步骤如下:
在App1中配置FileProvider
- 在
res/xml目录下创建file_paths.xml,指定要共享的内部存储目录(比如App1内部存储下的shared子目录):<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="shared_files" path="shared/"/> </paths> - 在App1的
AndroidManifest.xml中注册FileProvider:<provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.app1.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider>
- 在
App1给App2授权访问
- 当需要让App2访问目标文件时,App1生成文件Uri并授予临时读取权限:
val targetFile = File(context.filesDir, "shared/your_target_file.txt") val fileUri = FileProvider.getUriForFile(context, "com.your.app1.fileprovider", targetFile) // 给App2的包名授予临时读取权限 context.grantUriPermission("com.your.app2", fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION) - 之后App2就能直接通过这个Uri读取文件,全程无用户交互:
val inputStream = contentResolver.openInputStream(fileUri) // 读取文件内容逻辑...
这种方式的权限是临时可控的,也能配置持久化授权(需提前约定App2的包名),安全性比旧的同
userId方案高很多。- 当需要让App2访问目标文件时,App1生成文件Uri并授予临时读取权限:
如果需要更灵活的权限控制,你也可以自定义ContentProvider,自己实现文件查询、读取逻辑,只允许指定包名的App(比如App2)访问,适合复杂的文件共享场景。
二、外部存储文件夹加密方案
对于外部存储的文件夹加密,有两种主流实现路径:
1. 系统自带API:EncryptedFile(API 23+)
Android原生提供了EncryptedFile类,可对单个文件加密,若要加密整个文件夹,只需遍历文件夹内所有文件逐个处理即可。密钥建议存在Android Keystore中,避免硬编码泄露:
// 创建并存储加密密钥到Keystore val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore") keyGenerator.init(KeyGenParameterSpec.Builder("my_encryption_key", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()) val secretKey = keyGenerator.generateKey() // 加密外部存储中的文件 val encryptedFile = EncryptedFile.Builder( context, File(Environment.getExternalStorageDirectory(), "encrypted_folder/target.txt"), secretKey, EncryptedFile.FileEncryptionScheme.AES_GCM_NO_PADDING ).build() // 写入文件内容逻辑...
2. 第三方加密库
如果觉得系统API不够灵活,这些第三方库可以帮你简化文件夹加密流程:
- Tink:Google官方维护的加密库,支持文件加密、对称加密等多种场景,文档完善,安全性有保障,适合批量处理文件夹内的文件。
- Conceal:Facebook开源的轻量加密库,API简单易用,能快速实现文件加密,但近几年维护频次较低,需要注意版本兼容性。
- 若需要底层控制,也可以基于
CipherInputStream/CipherOutputStream自己实现文件夹遍历加密,但要做好密钥管理和异常处理。
不管用哪种方式,都要注意:外部存储的加密文件仍需申请对应存储权限(API 33+需READ_MEDIA_IMAGES等细粒度权限),且密钥一定要存在Android Keystore中,不要明文存储在代码或SharedPreferences里。
内容的提问来源于stack exchange,提问作者Introhart




