In this Android app tutorial, we will learn how to auto-sync Google Drive API in order to let Android users access and download the files from Google Drive to an Android app.
Table of Contents
This tutorial for Android Google Drive Sync is useful to those entrepreneurs who are looking to develop an android app for their own business & access all the data backed up with the help of Google Drive.
What is Google Drive?
Google Drive is a cloud-based storage service provided by Google. It is similar to other cloud storage services and is used to expand the storage capacity for keeping files beyond the limits of a hard drive. It syncs all stored documents, photos and many more files across a user’s device, including mobile devices, tablets and PCs.
Google provides 15 GB of free cloud storage space to every user for signing up & creating a Gmail account. However, it’s necessary to know that all of this 15 GB free space is divided & shared between Gmail, Google Drive (Microsoft Office Docs, Presentations, Spreadsheet etc), Google Photos as well.
How Does it Work?
By signing up, a user can create a Google account which can be used to access Gmail, Google Play store, Google Drive, Google Photos and many other services. Once the google account is created, a user can log in into the account and access Google Drive from its menu to browse the stored files.
Benefits of Google Drive Sync
The main benefit of signing up for a google account and auto-sync google drive is that it can be accessed via the browser, on desktop and laptop or via smartphone also, which allows users to store & access data from anywhere as per their ease.
Google also provides the auto-sync features so that all the data of a user’s device can be automatically synced & uploaded to Google Drive without asking users for permission every time.
Moreover, accessing and storing data on the Google drive is much secure as all the data is encrypted and decrypted using 128-bit advanced encryption standard (AES) along with Transport Layer Security (TLS) standard when it goes from a user’s device and reaches to Google’s cloud storage.
Read Here: How to Use Android Wrap_Content
Want To Create An Android Application?
Looking to Create An Android app? Get in touch with our experienced Android app developers for a free consultation.
Let’s see How to Auto-sync Google Drive in Android
Create a new project in the Android Studio
Add package name & configuration
Create a new project in the Android Studio
Add dependencies in your build.gradle file which is an in-app module
implementation 'androidx.multidex:multidex:2.0.1' implementation "com.google.android.gms:play-services-auth:16.0.1" implementation 'com.google.http-client:google-http-client-gson:1.26.0' implementation 'com.google.api-client:google-api-client-android:1.26.0' implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') { exclude group: 'com.google.guava' }
also, add packagingOptions in android { }
packagingOptions { exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/LICENSE' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/license.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/notice.txt' exclude 'META-INF/ASL2.0' }
Create a new project in the Google API console
Enable Google Drive API from APIs & Services -> Library -> Google Drive API
Add Application Name in OAuth consent screen
Add scope -> /auth/drive.file
Now Create Credentials from APIs & Services -> Credentials -> Create credentials -> Create OAuth client ID
just copy Client ID & Client Secret and paste to the string.xml file
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.spaceo.gdrivesyncdemo"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:usesCleartextTraffic="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> </manifest>
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/btnBackup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Backup" /> <Button android:id="@+id/btnRestore" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="24dp" android:text="Restore" /> </LinearLayout>
DriveServiceHelper.java
package com.spaceo.gdrivesyncdemo.util; import androidx.core.util.Pair; import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.Tasks; import com.google.api.client.http.InputStreamContent; import com.google.api.services.drive.Drive; import com.google.api.services.drive.model.File; import com.google.api.services.drive.model.FileList; import java.io.*; import java.util.Collections; import java.util.concurrent.Executor; import java.util.concurrent.Executors; /** * A utility for performing read/write operations on Drive files via the REST API and opening a * file picker UI via Storage Access Framework. */ public class DriveServiceHelper { private final Executor mExecutor = Executors.newSingleThreadExecutor(); private final Drive mDriveService; public DriveServiceHelper(Drive driveService) { mDriveService = driveService; } public Task<String> uploadFile(String name, java.io.File fileTest) { return Tasks.call(mExecutor, () -> { File metadata = new File() .setParents(Collections.singletonList("root")) .setMimeType("text/plain") .setName(name); InputStream targetStream = new FileInputStream(fileTest); InputStreamContent inputStreamContent = new InputStreamContent("text/plain", targetStream); File googleFile = mDriveService.files().create(metadata, inputStreamContent).execute(); if (googleFile == null) { throw new IOException("Null result when requesting file creation."); } return googleFile.getId(); }); } /** * Opens the file identified by {@code fileId} and returns a {@link Pair} of its name and * contents. */ public Task<Pair<String, String>> readFile(String fileId) { return Tasks.call(mExecutor, () -> { // Retrieve the metadata as a File object. File metadata = mDriveService.files().get(fileId).execute(); String name = metadata.getName(); // Stream the file contents to a String. try (InputStream is = mDriveService.files().get(fileId).executeMediaAsInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } String contents = stringBuilder.toString(); return Pair.create(name, contents); } }); } /** * Returns a {@link FileList} containing all the visible files in the user's My Drive. * * <p>The returned list will only contain files visible to this app, i.e. those which were * created by this app. To perform operations on files not created by the app, the project must * request Drive Full Scope in the <a href="https://play.google.com/apps/publish">Google * Developer's Console</a> and be submitted to Google for verification.</p> */ public Task<FileList> queryFiles() { return Tasks.call(mExecutor, () -> mDriveService.files().list().setSpaces("drive").execute()); } }
RunTimePermission.kt
package com.spaceo.gdrivesyncdemo.util import android.content.pm.PackageManager import android.os.Build import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat open class RunTimePermission : AppCompatActivity() { private var callback: ((Boolean) -> Unit)? = null fun requestPermission(permissions: Array<String>, callback: (isGranted: Boolean) -> Unit) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { var granted = true for (permission in permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { granted = false break } } if (granted) { callback(true) } else { this.callback = callback requestPermissions(permissions, Integer.MAX_VALUE) } } else callback(true) } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == Integer.MAX_VALUE) { var granted = true for (i in 0 until grantResults.size) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { granted = false break } } if (granted) callback?.invoke(true) else onDenied() } } private fun onDenied() { callback?.invoke(false) } }
MainActivity.kt
package com.spaceo.gdrivesyncdemo import android.content.Intent import android.os.Bundle import android.os.Environment import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInClient import com.google.android.gms.auth.api.signin.GoogleSignInOptions import com.google.android.gms.common.Scopes import com.google.android.gms.common.api.Scope import com.google.api.client.extensions.android.http.AndroidHttp import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential import com.google.api.client.json.gson.GsonFactory import com.google.api.services.drive.Drive import com.google.api.services.drive.DriveScopes import com.spaceo.gdrivesyncdemo.util.DriveServiceHelper import com.spaceo.gdrivesyncdemo.util.RunTimePermission import kotlinx.android.synthetic.main.activity_main.* import java.io.File import java.io.FileOutputStream import java.io.FileWriter import java.lang.StringBuilder import java.util.* import java.util.jar.Manifest class MainActivity : RunTimePermission() { private val RQ_GOOGLE_SIGN_IN = 210 private val BACKUP_FILE = "test.txt" private var isRestore = false private var mGoogleApiClient: GoogleSignInClient? = null private var mDriveServiceHelper: DriveServiceHelper? = null private var lastUploadFileId: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) btnBackup.setOnClickListener { requestPermission(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { isGranted -> if (isGranted) { isRestore = false if (mDriveServiceHelper == null) googleAuth() else { val uploadTask = mDriveServiceHelper?.uploadFile(BACKUP_FILE, generateFile()) uploadTask?.addOnCompleteListener { lastUploadFileId = uploadTask.result println("lastUploadFileId==>$lastUploadFileId") Toast.makeText(this@MainActivity, "Backup upload successfully", Toast.LENGTH_LONG).show() } } } } } btnRestore.setOnClickListener {requestPermission(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { isGranted -> if (isGranted) { isRestore = true if (mDriveServiceHelper == null) googleAuth() else { if (null != lastUploadFileId) { val downloadTask = mDriveServiceHelper?.readFile(lastUploadFileId) downloadTask?.addOnCompleteListener { println("Name==>${downloadTask.result?.first}") println("Content==>${downloadTask.result?.second}") Toast.makeText(this@MainActivity, "Backup download successfully", Toast.LENGTH_LONG) .show() } } } } } } } private fun googleAuth() { val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestServerAuthCode(getString(R.string.web_client_id)) .requestScopes(Scope(Scopes.PROFILE), Scope("https://www.googleapis.com/auth/drive.file")) .build() mGoogleApiClient = GoogleSignIn.getClient(this, signInOptions) startActivityForResult(mGoogleApiClient!!.signInIntent, RQ_GOOGLE_SIGN_IN) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == RQ_GOOGLE_SIGN_IN && resultCode == RESULT_OK) { val task = GoogleSignIn.getSignedInAccountFromIntent(data) task.addOnSuccessListener { val credential = GoogleAccountCredential.usingOAuth2( this, Collections.singleton(DriveScopes.DRIVE_FILE) ) credential.selectedAccount = it.account val googleDriveService = Drive.Builder( AndroidHttp.newCompatibleTransport(), GsonFactory(), credential ).setApplicationName(getString(R.string.app_name)).build() mDriveServiceHelper = DriveServiceHelper(googleDriveService) if (isRestore) { if (null != lastUploadFileId) { val downloadTask = mDriveServiceHelper?.readFile(lastUploadFileId) downloadTask?.addOnCompleteListener { println("Name==>${downloadTask.result?.first}") println("Content==>${downloadTask.result?.second}") Toast.makeText(this@MainActivity, "Backup download successfully", Toast.LENGTH_LONG).show() } } } else { val uploadTask = mDriveServiceHelper?.uploadFile(BACKUP_FILE, generateFile()) uploadTask?.addOnCompleteListener { lastUploadFileId = uploadTask.result println("lastUploadFileId==>$lastUploadFileId") Toast.makeText(this@MainActivity, "Backup upload successfully", Toast.LENGTH_LONG).show() } } } } } private fun generateFile(): File { Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).mkdir() val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), BACKUP_FILE) if (!file.exists()) file.createNewFile() val data = StringBuilder() for (i in 0..50) { data.append("$i. First string is here to be written. First string is here to be written.") } val fileOutputStream = FileOutputStream(file, true) fileOutputStream.write(data.toString().toByteArray()) return file } override fun onDestroy() { super.onDestroy() if (null != mGoogleApiClient) mGoogleApiClient!!.signOut() } }
Conclusion
Using the above Google Drive Auto-sync example, we learned how to easily backup files from an Android device to Google Drive (Cloud backup) and also retrieve anytime. It also saves the memory on a mobile device as well as on Laptop, Desktop. You can get the source of this Android app tutorial from Github.
Moreover, if you are looking to create an android app and wish to add this functionality within the app, you can get in touch with us through below contact us form. One of our sales representatives will get back to you shortly. The consultation is absolutely free of cost.