Setup Android Google Drive REST API (Java/Kotlin)

NOTE: Google Drive REST API is the replacement for the deprecated Google Drive Android API.

Dependencies

Setup depedencies in app module's build.gradle.

dependencies {
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation('com.google.api-client:google-api-client-android:1.23.0') {
        exclude group: 'org.apache.httpcomponents'
        exclude module: 'guava-jdk5'
    }
    // https://mvnrepository.com/artifact/com.google.apis/google-api-services-drive
    implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
        exclude group: 'org.apache.httpcomponents'
        exclude module: 'guava-jdk5'
    }
}

Google Cloud Platform Project and Enable API

You need to create a new or use existing Google Cloud Platform project.

Enable Google Drive API in API Library.

Make sure Credential - OAuth 2.0 client IDs contain an entry with

Sometimes this entry is auto created by Google Service. If the entry does not exist, you need to create an entry.

NOTE: Refer to Connecting and Authorizing the Google Drive Android API.

Code

The following sample will

  • Sign-in to request Google Drive permission
  • List all google sheets file
  • Utilize kotlin coroutines to launch job in background thread
  • User Timber to log output
@ExperimentalCoroutinesApiclass GoogleDriveListActivity : AppCompatActivity(), CoroutineScope by MainScope() {    companion object {        private const val REQUEST_SIGN_IN = 1    }    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.googledrivelist)        requestSignIn()    }    override fun onDestroy() {        super.onDestroy()        cancel()    }    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {        Timber.d("onActivityResult=$requestCode")        when(requestCode) {            REQUEST_SIGN_IN -> {                if (resultCode == RESULT_OK && data != null) {                    handleSignInResult(data)                }                else {                    Timber.d("Signin request failed")                }            }        }        super.onActivityResult(requestCode, resultCode, data)    }    private fun buildGoogleSignInClient(): GoogleSignInClient {        val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)            // .requestScopes(Drive.SCOPE_FILE)            // .requestScopes(Scope(DriveScopes.DRIVE_FILE))             .requestScopes(Scope(DriveScopes.DRIVE))            .build()        return GoogleSignIn.getClient(this, signInOptions)    }    private fun handleSignInResult(result: Intent) {        GoogleSignIn.getSignedInAccountFromIntent(result)            .addOnSuccessListener { googleAccount ->                Timber.d("Signin successful")                // Use the authenticated account to sign in to the Drive service.                val credential = GoogleAccountCredential.usingOAuth2(                    this, listOf(DriveScopes.DRIVE_FILE)                )                credential.selectedAccount = googleAccount.account                val googleDriveService = Drive.Builder(                    AndroidHttp.newCompatibleTransport(),                    JacksonFactory.getDefaultInstance(),                    credential)                    .setApplicationName(getString(R.string.app_name))                    .build()                // https://developers.google.com/drive/api/v3/search-files                // https://developers.google.com/drive/api/v3/search-parameters                // https://developers.google.com/drive/api/v3/mime-types                launch(Dispatchers.Default) {                    var pageToken: String? = null                    do {                        val result = googleDriveService.files().list().apply {                            q = "mimeType='application/vnd.google-apps.spreadsheet'"                            spaces = "drive"                            fields = "nextPageToken, files(id, name)"                            this.pageToken = pageToken                        }.execute()                        for (file in result.files) {                            Timber.d("name=${file.name}, id=${file.id}")                        }                    } while (pageToken != null)                }            }            .addOnFailureListener { e ->                Timber.e(e, "Signin error")            }    }    private fun requestSignIn() {        val client = buildGoogleSignInClient()        startActivityForResult(client.signInIntent, REQUEST_SIGN_IN)    }}

NOTE: If you bump into error Unresolved references: DriveScopes, make sure you are not using the deprecated com.google.android.gms:play-services-drive. Use com.google.apis:google-api-services-drive instead.

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.