How to connecting to Google Drive from an Android App

This sample demonstrates how to connect to an individual’s Google Drive* online storage service from an Android application. I’ll be describing the sections of code that are executed based on the usage flow of the app. This application is based on the Google Drive sample located here. Before you start building this sample, please follow the instructions in the previous link for registering your application with Google Cloud Console.
Like most Android applications, this one begins in the onCreate function of MainActivity. In this function, you can see the credentials for connecting to the Google Drive account are set up and an activity is started to prompt the user to select their Google account from the registered accounts on the device, or to enter a new one.
mCredential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(DriveScopes.DRIVE));
        startActivityForResult(mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);

After this, the function continues to set up the button listeners and the ListView listener.
Now that the basic UI is configured, the app waits for user input via the download and upload buttons. If the user presses the download button, the OnClickListener for that button launches an Intent that allows the user to select the application to pick media files from the device’s storage.
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() 
{
 public void onClick(View v) 
 {
 final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
 galleryIntent.setType("*/*");
 startActivityForResult(galleryIntent, RESULT_STORE_FILE);
 }
});
Since the Intent was started with startActivityForResult, when it returns, the main activity’sonActivityResult function will be called with RESULT_STORE_FILE. The URI of the file selected by the user can be obtained from data.getData().
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) 
{
 switch (requestCode) 
 {
  …
  case RESULT_STORE_FILE:
   mFileUri = data.getData();
   // Save the file to Google Drive
          saveFileToDrive();
   break;
 }
}
With this URI, the file can be saved to the Drive, which is done with the call to saveFileToDrive(). All communication to the Drive account with the Drive APIs is done in a new thread to ensure that it doesn’t slow down the main UI thread, causing the UI to become slow and laggy.
private void saveFileToDrive() 
{
Thread t = new Thread(new Runnable() 
     {
      @Override
      public void run() 
      {
   …
      }
     });
     t.start();
}
Within the run function, a new URI is created based on the real path to the media file’s contents. This is because the path that’s associated with the URI that’s returned from the Gallery Intent is a virtual path that doesn’t work with the upload feature of the Google Drive API. Here we’re getting the physical path and creating a new URI from it to upload to Google Drive.
// Create URI from real path
String path;
path = getPathFromUri(mFileUri);
mFileUri = Uri.fromFile(new java.io.File(path));
…
 java.io.File fileContent = new java.io.File(mFileUri.getPath());
Then FileContent and File variables are created to pass into the Google Drive APIs to upload the file’s content to the user’s Google Drive. A File’s object is created from the Service object created in OnCreate, and its Insert function is used to prepare the media file’s content to be uploaded. Then execute is called to actually push the content to the Google Drive in the cloud.
FileContent mediaContent = new FileContent(cR.getType(mFileUri), fileContent);
// File's meta data. 
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType(cR.getType(mFileUri));
com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.Insert i1 = f1.insert(body, mediaContent);
File file = i1.execute();
At this point, the upload is complete, and the user can view the file in the root of their Google Drive account.
Next the user can select the download button. Once pressed, the getDriveContents function is called.
final Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener()
{
 public void onClick(View v) 
 {
 getDriveContents();
 }
});
getDriveContents starts a new thread to download a list of file names of all the content in the Google Drive account.
private void getDriveContents()
{
 Thread t = new Thread(new Runnable() 
 {
  @Override
  public void run() 
  {
   mResultList = new ArrayList(); … } }); t.start(); }
Within getDriveContents, a FileList object is set up and used to request the list of files. In order not to get a list containing every object in the root folder and every object in the trash folder, the Q value is set with the string “trashed=false”. After all the pages of file data have been obtained and stored in the ArrayList of Files, the ListView in the UI is populated to show users which files are on their Google Drive accounts to download.
com.google.api.services.drive.Drive.Files f1 = mService.files();
com.google.api.services.drive.Drive.Files.List request = null;
    
do 
{
 try 
 { 
  request = f1.list();
  request.setQ("trashed=false");
  com.google.api.services.drive.model.FileList fileList = request.execute();
      
  mResultList.addAll(fileList.getItems());

  request.setPageToken(fileList.getNextPageToken());
 } catch (UserRecoverableAuthIOException e) {
  startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
 } catch (IOException e) {
  e.printStackTrace();
  if (request != null)
  {
  request.setPageToken(null);
  }
 }
} while (request.getPageToken() !=null && request.getPageToken().length() > 0);
    
populateListView();
populateListView pulls the file names from the ArrayList and stores them in a simple array of strings. They can then be used with an ArrayAdapter to populate the ListView. Once the ListView is populated, the app is waiting for user input again.
At this point, the user can select a file name from the ListView and its OnItemClickListener function will be called to handle the selection.
OnItemClickListener mMessageClickedHandler = new OnItemClickListener() 
{
 public void onItemClick(AdapterView parent, View v, int position, long id) 
 {
  downloadItemFromList(position);
 }
};
Now downloadItemFromList is called with the position in the list that was selected. A new thread is spawned since communication with Google Drive will be occurring again. Once the ListView selection is associated with the correct file from the ArrayList of Files, that particular file has a download URL that can be used to set up a Request for an HTTP response. Once this is setup, execute can be called to begin the download of the file’s contents. The file’s contents are returned in the form of an InputStream.
com.google.api.client.http.HttpResponse resp = 
 mService.getRequestFactory()
 .buildGetRequest(new GenericUrl(tmp.getDownloadUrl()))
 .execute();
InputStream iStream = resp.getContent();
try 
{
 final java.io.File file = new java.io.File(Environment
  .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(), 
  tmp.getTitle());
 showToast("Downloading: " + tmp.getTitle() + " to " + Environment
 .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
 storeFile(file, iStream);
} finally {
 iStream.close();
}
This InputStream can be used in conjunction with an OutputStream to store the file to a directory on the devices internal or external storage (SD card).
private void storeFile(java.io.File file, InputStream iStream)
{
 try 
 {
  final OutputStream oStream = new FileOutputStream(file);
  try
  {
   try
   {
    final byte[] buffer = new byte[1024];
    int read;
    while ((read = iStream.read(buffer)) != -1)
    {
     oStream.write(buffer, 0, read);
    }
    oStream.flush();
   } finally {
    oStream.close();
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 } catch (IOException e) {
  e.printStackTrace();
 }
}
Once the file is written to storage, the user can select to download another file or upload a new one.
There are many more features of the Drive API that you can use to write exciting Android applications that interact with user’s Google Drive accounts. For more information on the Google Drive API, please see:https://developers.google.com/drive/v2/reference/.

1 comment:

  1. Starting a business is very easy task. On the off chance that you need to figure out how to make money on the web, you have to have great business plans.

    ReplyDelete