Android 10及以下无权限实现用户信息留存的技术咨询
Android 10及以下版本无权限留存用户信息方案(卸载重装恢复数据)
方案1:Android系统自动备份服务(Auto Backup for Apps)
这是最贴合需求的原生方案,无需申请权限、无需用户账号,依赖系统自带备份机制:
- 原理:Android 6.0(API 23)及以上系统默认开启应用自动备份,会定期将应用私有目录(如
/data/data/[包名]/files、shared_prefs、databases等)的数据备份至云端(Google Drive,国内定制ROM多适配本地备份或自有云服务),卸载重装后,只要用户设备开启「备份与恢复」功能,系统会自动恢复备份数据。 - 配置步骤:
- 在
AndroidManifest.xml中显式开启备份(默认已开启,可明确声明):<application android:allowBackup="true" android:fullBackupContent="@xml/backup_rules"> ... </application> - 在
res/xml/目录下创建backup_rules.xml,指定需备份的内容(示例:备份所有SharedPreferences和files目录文件):<?xml version="1.0" encoding="utf-8"?> <full-backup-content> <include domain="sharedpref" path="."/> <include domain="file" path="."/> </full-backup-content>
- 在
- 注意事项:
- 单应用备份上限为50MB,适合存储游戏存档这类小体积数据。
- 国内定制ROM的备份逻辑可能存在差异,需覆盖主流机型(小米、华为、OPPO等)测试。
方案2:MediaStore存储非媒体文件(Android 10专属适配)
针对Android 10(API 29),可通过MediaStore的公共集合存储数据,无需申请WRITE_EXTERNAL_STORAGE权限:
- 原理:Android 10引入分区存储后,应用无需权限即可向MediaStore的公共目录插入非媒体文件,卸载后文件不会被删除,重装后可通过查询MediaStore恢复数据。
- 存储数据示例:
fun saveDataToMediaStore(context: Context, data: String, fileName: String) { val contentValues = ContentValues().apply { put(MediaStore.Downloads.DISPLAY_NAME, fileName) put(MediaStore.Downloads.MIME_TYPE, "text/plain") put(MediaStore.Downloads.RELATIVE_PATH, "Documents/[你的应用标识文件夹]") } val uri = context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) uri?.let { context.contentResolver.openOutputStream(it)?.use { outputStream -> outputStream.write(data.toByteArray()) } } } - 读取数据示例:
fun readDataFromMediaStore(context: Context, fileName: String): String? { val projection = arrayOf(MediaStore.Downloads._ID, MediaStore.Downloads.DATA) val selection = "${MediaStore.Downloads.DISPLAY_NAME} = ?" val selectionArgs = arrayOf(fileName) context.contentResolver.query( MediaStore.Downloads.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null )?.use { cursor -> if (cursor.moveToFirst()) { val dataColumn = cursor.getColumnIndex(MediaStore.Downloads.DATA) val filePath = cursor.getString(dataColumn) return File(filePath).readText() } } return null } - 注意事项:
- Android 9及以下版本仍需申请
WRITE_EXTERNAL_STORAGE权限,若要完全无权限,此方案仅适配Android 10,需结合方案1覆盖全版本。 - 存储的文件会在文件管理器中可见,建议加密数据或使用隐蔽命名避免误删。
- Android 9及以下版本仍需申请
方案3:数据加密存储(增强安全性)
无论采用哪种存储方案,建议对游戏存档等敏感数据加密,防止篡改或泄露:
- 可使用Android原生
KeyStore生成密钥,通过AES加密数据后再存储,示例代码片段:fun encryptData(context: Context, plainText: String): String { // 省略KeyStore初始化与密钥生成逻辑 val cipher = Cipher.getInstance("AES/GCM/NoPadding") cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(context)) val encryptedBytes = cipher.doFinal(plainText.toByteArray()) return Base64.encodeToString(encryptedBytes, Base64.DEFAULT) }
内容的提问来源于stack exchange,提问作者Summer-Yang
相关产品推荐
相关产品推荐

