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

如何将本地应用数据库备份至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范围(仅访问应用创建的文件,安全性更高)

备份流程

  1. 定位本地.db文件
    获取数据库文件路径,以默认SQLite数据库为例:

    val dbFilePath = context.getDatabasePath("your_database_name.db").absolutePath
    val dbFile = File(dbFilePath)
    
  2. 构建Drive客户端与文件元数据
    先通过Google登录获取授权账户,再构建Drive客户端,同时设置备份文件的元数据(文件名、类型等):

    // 假设已完成Google账户登录,获取driveResourceClient实例
    val metadata = MetadataChangeSet.Builder()
        .setTitle("db_backup_${System.currentTimeMillis()}.db") // 带时间戳区分版本
        .setMimeType("application/x-sqlite3")
        .build()
    
  3. 上传文件至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 {
                // 处理上传失败(网络异常、权限不足等)
            }
    }
    

恢复流程

  1. 选择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)
        }
    
  2. 下载并覆盖本地数据库
    在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:28:11