Do you need to upload folders, or upload files to Google Drive via Google API v3? Then this guide is for you!
As you may have noticed, the resources found online are often old, and even on the official website they are not available for Kotlin, and the Google public GitHub repo for Android are old.
What will I be able to do after reading this article?
This guide will show you how to integrate the Google API v3 within your android application written in Kotlin in 2023 and then how to create a directory and upload files into it. Let’s go!
1. Prerequisites
You must have integrated Google Sign-In within your application, and then enabled the Google Drive API within the GCP project.
2. Dependencies
Let’s define the dependencies needed to use the Drive API inside the build.gradle
of our app:
// ... | |
// coroutines | |
// Guava | |
implementation "com.google.guava:guava:24.1-jre" | |
// Guava fix | |
implementation "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" | |
//Drive | |
implementation('com.google.api-client:google-api-client-android:1.23.0') { | |
exclude group: 'org.apache.httpcomponents' | |
exclude module: 'guava-jdk5' | |
} | |
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') { | |
exclude group: 'org.apache.httpcomponents' | |
exclude module: 'guava-jdk5' | |
} |
Google Drive API v3 Android Dependencies (Feb, 2023)
Unsplash photo
3. Google Drive Instance
Now that we have everything ready, let’s get deep down to the code!
3.a) Helper Functions
Let‘s first prepare a helper function for the SignIn phase. In this function, it’s important to pass the scopes we need to get the permission from the oAuth. DriveScopes.DRIVE_FILE
and DriveScopes.DRIVE
are the ones we need for creating files:
fun getGoogleSignInClient(context: Context): GoogleSignInClient { | |
val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) | |
.requestEmail() | |
.requestScopes(Scope(DriveScopes.DRIVE_FILE), Scope(DriveScopes.DRIVE)) | |
.build() | |
return GoogleSignIn.getClient(context, signInOptions) | |
} |
3.b) ActivityResultContract & SignIn
First, we need to define an ActivityResultContracts
to do the SignIn in Google:
val startForResult = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult -> | |
if (result.resultCode == Activity.RESULT_OK) { | |
val intent = result.data | |
if (result.data != null) { | |
val task: Task<GoogleSignInAccount> = | |
GoogleSignIn.getSignedInAccountFromIntent(intent) | |
/** | |
* handle [task] result | |
*/ | |
} else { | |
Toast.makeText(ctx, "Google Login Error!", Toast.LENGTH_LONG).show() | |
} | |
} | |
} |
Android Google SignIn ActivityResultContract
this can reside within the ViewModel or a helper class, and we can use it as an event with the click of a login button:
Button( | |
onClick = { | |
startForResult.launch(getGoogleSignInClient(ctx).signInIntent) | |
}, | |
modifier = Modifier() | |
) { | |
Text(text = "Sign in with Google") | |
} |
Jetpack Compose Button
3.c) Google Drive Instance
Now you can request an instance of the Drive API within your app, such as your ViewModel or in a HelperClass of your Business Logic:
GoogleSignIn.getLastSignedInAccount(context)?.let { googleAccount -> | |
// get credentials | |
val credential = GoogleAccountCredential.usingOAuth2( | |
context, listOf(DriveScopes.DRIVE, DriveScopes.DRIVE_FILE) | |
) | |
credential.selectedAccount = googleAccount.account!! | |
// get Drive Instance | |
val drive = Drive | |
.Builder( | |
AndroidHttp.newCompatibleTransport(), | |
JacksonFactory.getDefaultInstance(), | |
credential | |
) | |
.setApplicationName(context.getString(R.string.app_name)) | |
.build() | |
} |
Request a Drive Instance
4. Create Google Drive Folder
The biggest things now have been done!
Within the event of a button click, in your ViewModel or in your business logic you can now create a Google Drive folder as follows:
viewModelScope.launch(Dispatchers.IO) { | |
// Define a Folder | |
val gFolder = com.google.api.services.drive.model.File() | |
// Set file name and MIME | |
gFolder.name = "My Cool Folder Name" | |
gFolder.mimeType = "application/vnd.google-apps.folder" | |
// You can also specify where to create the new Google folder | |
// passing a parent Folder Id | |
val parents: MutableList<String> = ArrayList(1) | |
parents.add("your_parent_folder_id_here") | |
gFolder.parents = parents | |
drive.Files().create(gFolder).setFields("id").execute() | |
} |
Create a Google Drive Folder
For more information on what parameters you can set, I suggest you delve into the official guide.
4. Create Google Drive File
As simple as creating a folder, you can now create a file!
Job Offers
for (file in files) { | |
val gfile = com.google.api.services.drive.model.File() | |
val fileContent = FileContent("your_mime", file) | |
gfile.name = file.name | |
val parents: MutableList<String> = ArrayList(1) | |
parents.add("folder_id") // Here you need to get the parent folder id | |
gfile.parents = parents | |
drive.Files().create(gfile, fileContent).setFields("id").execute() | |
} |
Create a File on Google Drive
And there you have it! now you know how to integrate the Google Drive API v3 within your awesome Android app!
If you are interested in a more in-depth look at how to do authentication setup for SignIn, or how to create the project on the Google Cloud Platform and manage oAuth with scopes let me know in the comments!
My advice is to always follow the official guidelines and clean code writing guidelines.
If you like my article, please don’t forget to click 👏👏👏 to recommend it to others 👏👏👏.
Feel free to ask questions, make comments, or propose a better solution. Don’t forget to follow me on Twitter and GitHub!
This article was originally published on proandroiddev.com