You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 10及以下无权限实现用户信息留存的技术咨询

Android 10及以下版本无权限留存用户信息方案(卸载重装恢复数据)

方案1:Android系统自动备份服务(Auto Backup for Apps)

这是最贴合需求的原生方案,无需申请权限、无需用户账号,依赖系统自带备份机制:

  • 原理:Android 6.0(API 23)及以上系统默认开启应用自动备份,会定期将应用私有目录(如/data/data/[包名]/files、shared_prefs、databases等)的数据备份至云端(Google Drive,国内定制ROM多适配本地备份或自有云服务),卸载重装后,只要用户设备开启「备份与恢复」功能,系统会自动恢复备份数据。
  • 配置步骤:
    1. 在AndroidManifest.xml中显式开启备份(默认已开启,可明确声明):
      <application
          android:allowBackup="true"
          android:fullBackupContent="@xml/backup_rules">
          ...
      </application>
      
    2. 在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覆盖全版本。
    • 存储的文件会在文件管理器中可见,建议加密数据或使用隐蔽命名避免误删。

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:57:49