如何将本地应用数据库备份至Google Drive并从其恢复?
本地数据库备份至Google Drive及恢复方案
准备工作
- 集成Google Drive SDK:在Google Cloud Console创建项目并启用Drive API,配置OAuth 2.0客户端ID(绑定应用SHA-1指纹),项目中添加依赖:
implementation 'com.google.android.gms:play-services-drive:20.1.0' - 权限配置:
- 若数据库存放在应用私有目录,无需外部存储权限;若在公共存储,需申请
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE(Android 10以下)或MANAGE_EXTERNAL_STORAGE(Android 10+) - 通过OAuth授权获取Drive访问权限,推荐使用
DriveScopes.DRIVE_FILE范围(仅访问应用创建的文件,安全性更高)
- 若数据库存放在应用私有目录,无需外部存储权限;若在公共存储,需申请
备份流程
定位本地.db文件
获取数据库文件路径,以默认SQLite数据库为例:val dbFilePath = context.getDatabasePath("your_database_name.db").absolutePath val dbFile = File(dbFilePath)构建Drive客户端与文件元数据
先通过Google登录获取授权账户,再构建Drive客户端,同时设置备份文件的元数据(文件名、类型等):// 假设已完成Google账户登录,获取driveResourceClient实例 val metadata = MetadataChangeSet.Builder() .setTitle("db_backup_${System.currentTimeMillis()}.db") // 带时间戳区分版本 .setMimeType("application/x-sqlite3") .build()上传文件至Drive
创建Drive内容对象,将本地数据库文件写入后上传:driveResourceClient.createContents().addOnSuccessListener { driveContents -> FileInputStream(dbFile).use { input -> input.copyTo(driveContents.outputStream) } // 上传到Drive根目录,也可指定父文件夹ID driveResourceClient.createFile(null, metadata, driveContents) .addOnSuccessListener { // 备份成功,可记录该文件的Drive ID方便后续恢复 val backupFileId = it.driveId.encodeToString() } .addOnFailureListener { // 处理上传失败(网络异常、权限不足等) } }
恢复流程
选择Drive上的备份文件
调用Drive的文件选择器,让用户选择目标备份文件:val openOptions = OpenFileActivityOptions.Builder() .setMimeType(arrayOf("application/x-sqlite3")) // 仅显示.db文件 .build() driveClient.newOpenFileActivityIntentSender(openOptions) .addOnSuccessListener { sender -> startIntentSenderForResult(sender, REQUEST_RESTORE_DB, null, 0, 0, 0) }下载并覆盖本地数据库
在onActivityResult中处理选择结果,下载文件并替换本地数据库(必须先关闭当前数据库连接):override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_RESTORE_DB && resultCode == Activity.RESULT_OK) { val driveId = data?.getParcelableExtra<DriveId>(OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID) driveId?.let { // 关闭当前数据库连接,避免文件被占用 yourDbHelper.close() driveResourceClient.getContents(it.asDriveFile()) .addOnSuccessListener { driveContents -> val localDbFile = File(context.getDatabasePath("your_database_name.db").absolutePath) FileOutputStream(localDbFile).use { output -> driveContents.inputStream.copyTo(output) } // 恢复完成,重新初始化数据库 yourDbHelper = YourDbHelper(context) } .addOnFailureListener { // 处理恢复失败 } } } }
关键注意事项
- 数据库连接管理:备份/恢复前必须关闭所有数据库连接,否则会出现文件无法读写的异常
- 版本兼容性:不同Android版本的存储权限规则不同,优先将数据库放在应用私有目录(
context.filesDir下)以避免权限问题 - 备份版本管理:通过文件名时间戳或Drive文件元数据的备注信息,区分不同时间的备份,方便用户选择恢复
- 错误处理:所有异步操作需添加失败监听,覆盖网络中断、权限被拒、文件损坏等场景
内容的提问来源于stack exchange,提问作者Hardeep Singh
相关产品推荐
相关产品推荐

