如何在Android中使用Google Drive API的备份服务

1,405 阅读4分钟

在Android中使用Google Drive API的备份服务

几乎每个Android应用都需要某种形式的云存储来保存用户的数据。Google Drive是基于云的存储解决方案之一。它的工作原理与其他云存储服务相似,即用于增加用户希望在丢失时恢复的重要文件的存储容量。

Google Drive可以在用户的所有设备上同步所有的文档、图像和其他类型的文件,包括手机、平板电脑和电脑。

前提条件

要完成本教程,你需要。

  • 对[Kotlin Coroutines]和higher order 函数有良好的理解。
  • 一个活跃的谷歌账户。如果你没有,你可以[在这里]创建一个。
  • 熟悉[谷歌]的登录认证。

开始使用

首先,启动一个安卓项目,在这个项目中你已经集成了谷歌登录认证。

设置依赖性

打开应用程序级别的build.gradle 文件,添加以下依赖项。

Kotlin Coroutines

implementation ('org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3-native-mt')

Google Drive API

implementation('com.google.api-client:google-api-client-android:1.23.0')
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0')

实例化Google Drive

为了使用Google Drive,我们需要构建一个Drive 对象。Drive是Google Drive API的一个类。它的用途包括上传、下载、搜索和调整Drive共享权限。

使用其构建器创建一个Drive实例的程序如下。

第1步

如前所述,我们需要一个使用你的安卓应用认证的谷歌账户。然后我们可以使用getLastSignedInAccount 功能获得最新的账户,如下图所示。

GoogleSignIn.getLastSignedInAccount(this)?.let { googleAccount -> }

第2步

为了访问用户的Google Drive内容,我们需要建立一个GoogleAccountCredential ,用DRIVE_FILE 的权限来验证签入的账户。这些权限是用来决定是否可以访问一个文件的。

val credential = GoogleAccountCredential.usingOAuth2(
    this, listOf(DriveScopes.DRIVE_FILE)
)
// select account
credential.selectedAccount = googleAccount.account!!

第3步

这是创建Drive 实例时的最后一步。在这里,我们需要使用它的构建器来构建Drive服务实例,将AndroidHttp,JacksonFactory, 和GoogleAccountCredential 作为参数。

我们可以将上述步骤合并为一个函数,如下图所示。

private fun getDriveService(): Drive? {
    GoogleSignIn.getLastSignedInAccount(this)?.let { googleAccount ->
        val credential = GoogleAccountCredential.usingOAuth2(
            this, listOf(DriveScopes.DRIVE_FILE)
        )
        credential.selectedAccount = googleAccount.account!!
        return Drive.Builder(
            AndroidHttp.newCompatibleTransport(),
            JacksonFactory.getDefaultInstance(),
            credential
        )
            .setApplicationName(getString(R.string.app_name))
            .build()
    }
    return null
}

如果用户已经登录并且有DRIVE_FILE 的权限,上述函数返回一个Drive 实例。否则,它返回null

如何访问Google Drive的内容

现在我们有一个Drive 实例,我们可以访问用户的Google Drive内容。我们在驱动器类中有一个名为files 的方法,它被用作访问器,用于从文件集合中发出请求。

files 函数的参数

  1. q- 是一个对文件结果进行排序的请求。
  2. spaces- 是一个存储数据的位置的列表。Google Drive将所有的材料存储在这三个不同的类别中的一个:Drive、appDataFolder和图片。在这里我们将使用驱动器。
  3. fields- 每个文件要求的数据,如id和名称。

下面的代码例子显示了如何访问drive 空间上的所有文件。

private fun accessDriveFiles() {
    getDriveService()?.let { googleDriveService ->
        CoroutineScope(Dispatchers.IO).launch {
            var pageToken: String?
            do {
                val result = googleDriveService.files().list().apply {
                    spaces = "drive"
                    fields = "nextPageToken, files(id, name)"
                    pageToken = this.pageToken
                }.execute()

                result.files.forEach { file ->
                    Log.d("FILE", ("name=${file.name} id=${file.id}"))
                }
            } while (pageToken != null)
        }
    }
}

这里我们使用了一个coroutine范围来启动一个coroutine,向Google Drive API发出请求。coroutine作用域是用来确保请求工作在后台执行的。

每个文件的nameid 被打印在logcat上。

如何上传文件到Google Drive

这涉及三个步骤。

第1步

首先,你需要从本地存储中构建一个你想上传的文件的实例。

val localFileDirectory = File(getExternalFilesDir("backup")!!.toURI())
val actualFile = File("${localFileDirectory}/$FILE_NAME_BACKUP")

第2步

创建Google Drive文件,并将文件名替换为真正的文件名。

val gFile = com.google.api.services.drive.model.File()
gFile.name = actualFile.name

第3步

创建一个FileContent ,包括实际文件的内容和MIME类型,然后如下图所示上传。

val fileContent = FileContent("text/plain", actualFile)
googleDriveService.Files().create(gFile,fileContent).execute()

将这些汇编成一个函数,我们有以下内容。

fun uploadFileToGDrive() {
    getDriveService()?.let { googleDriveService ->
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val localFileDirectory = File(getExternalFilesDir("backup")!!.toURI())
                val actualFile = File("${localFileDirectory}/FILE_NAME_BACKUP")
                val gFile = com.google.api.services.drive.model.File()
                gFile.name = actualFile.name
                val fileContent = FileContent("text/plain", actualFile)
                googleDriveService.Files().create(gFile, fileContent).execute()
            } catch (exception: Exception) {
                exception.printStackTrace()
            }
        }
    } ?: Toast.makeText(this, "Please Log In first!", LENGTH_SHORT).show()
}

如果用户没有登录,uploadFileToGDrive 函数将显示一个祝酒词。

如何从Google Drive下载文件

要从Drive获得一个文件,你需要把它的id 传递给服务的get() 方法并执行请求。

fun downloadFileFromGDrive(id : String){
    getDriveService()?.let {googleDriveService->
        CoroutineScope(Dispatchers.IO).launch {
            googleDriveService.Files().get(id).execute()
        }
    } ?: Toast.makeText(this, "Please Log In first!", LENGTH_SHORT).show()
}

如何修复使用Google Drive API时的崩溃问题

  • 确保用户用一个活跃的谷歌账户登录,并有DRIVE_FILE 的权限。
  • 在服务器端,确保文件在服务器上已经不存在。
  • 在客户端,确保文件在下载时不存在于本地存储中。

总结

在本教程中,我们已经介绍了访问Google Drive API的基本步骤,并使用它来从Google Drive上传和下载文件。你可以在一个更复杂的项目中以你想要的方式实现这些知识。