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

Android应用使用Google Drive API读取文件失败的问题求助

Android 使用Google Drive API读取文件遇到的问题

我正尝试在Android应用中使用Google Drive API读取PDF文件,目前仅需实现连接并获取Drive中的任意文件,但遇到了问题。

已完成的操作

  • 创建新的Google Cloud项目,启用Drive API并生成API密钥和OAuth客户端ID(二者使用相同SHA1是否正确?)
  • 在MainActivity.kt中编写了如下代码:
class MainActivity : AppCompatActivity() {

    private val fields = "nextPageToken, files(id, name)"
    private lateinit var  readButton: Button
    private var googleSignInClient: GoogleSignInClient? = null
    private var isFileRead = false
    private val accessDriveScope: Scope = Scope(Scopes.DRIVE_FILE)
    private val scopeEmail: Scope = Scope(Scopes.EMAIL)

private var launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
    {
        result ->
        if (result.resultCode == Activity.RESULT_OK){
            val data: Intent? = result.data
            try{
                val task = GoogleSignIn.getSignedInAccountFromIntent(data)
                task.getResult(ApiException::class.java)
                checkForGooglePermissions()
            }
            catch (e: ApiException){

            }

        }
    }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    readButton = findViewById(R.id.read)

    readButton.setOnClickListener{
        isFileRead = true
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestScopes(Scope(DRIVE_FILE))
            .build()

        googleSignInClient = GoogleSignIn.getClient(this,gso)

        val signInIntent = googleSignInClient?.signInIntent
        launcher.launch(signInIntent)
    }
}

private fun checkForGooglePermissions() {
    if (!GoogleSignIn.hasPermissions(
        GoogleSignIn.getLastSignedInAccount(this),
        accessDriveScope,
        scopeEmail
        )){
        GoogleSignIn.requestPermissions(
            this,
            1,
            GoogleSignIn.getLastSignedInAccount(this),
            accessDriveScope,
            scopeEmail
        )
    }
    else {       
        lifecycle.coroutineScope.launch { driveSetUp() }
    }
}

private suspend fun driveSetUp(){
        val mAccount = GoogleSignIn.getLastSignedInAccount(this)

        val credential = GoogleAccountCredential.usingOAuth2(
            this,
            Collections.singleton(Scopes.DRIVE_FILE)
        )

        credential.selectedAccount = mAccount?.account

        val googleDriveService = Drive.Builder(
            NetHttpTransport(),
            GsonFactory(),
            credential
        ).setApplicationName("My Drive Test").build()

        if (isFileRead){
            //Read from drive
            withContext(Dispatchers.Default){
                try {
                    val fileListJob = async {listDriveFiles(googleDriveService)}
                    val fileList = fileListJob.await()
                    for (item in fileList){
                        Log.d("MyLog", item.name)
                    }
                }
                catch (e: Exception){
                    //Handle error
                }
            }
        }
    }

private fun listDriveFiles(mDriveService: Drive): List<com.google.api.services.drive.model.File>
    {
        var result: FileList
        var pageToken: String? = null       
        do {
            result = mDriveService.files().list()
                .setQ("mimeType=text/plain")
                .setSpaces(DRIVE)
                .setFields(fields)
                .setPageToken(pageToken)
                .execute()
            pageToken = result.nextPageToken
        } while (pageToken != null)

        return result.files
    }
}
  • 运行应用时,会提示连接Google账户,但在执行val fileListJob = async {listDriveFiles(googleDriveService)}时失败,错误响应如图所示。

补充信息

编辑1

我的Android应用与Drive API的唯一关联是已将应用包名添加至API密钥和OAuth客户端ID中。我究竟哪里操作有误?我已经生成了API密钥。

编辑2

我按照官方文档尝试使用getAccountsByType()获取账户,但调用以下代码返回空列表(尽管手机中已添加3个Google账户):

val am: AccountManager = AccountManager.get(this) // "this" references the current Context
val accounts: Array<out Account> = am.getAccountsByType("com.google")

改用val accounts: Array<out Account> = am.accounts仅返回1个账户,其类型为com.osp.app.signin。

接下来我该如何登录Drive账户?未找到完整操作指南,恳请协助。

已添加的Manifest权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />

内容的提问来源于stack exchange,提问作者Amir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:53:12