Friday 14 December 2012

How to programmatically upload file from android to Google Drive (eclipse development)

For purpose I created out this post of tutorial simply felt sympathy to lack of practical + example documentation and a lot of mistake (found on "https://developers.google.com/drive/quickstart-android" ) support to programmatically upload file from Android to Google Drive by using Oath2 authority protocol (You must use it not other choises). Mostly if you have account setup on your gmail account on your android phone, it will automatically upload it to Google somethings known backend server which is not provide support to browseable but only sync it, but I preferred always "Do It Yourself (DIY)", with this ability you can master it to upload even sync your offline document , message, sms or contact details to your google drive for future see able or even your want to share it with your partners.

I've grind it until taken 13 day simply to under for all of these awesome Things!!!!

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.Download my copied android file attachment from "http://rapidgator.net/file/63338103/com.android.example.googledrivet.GoogleTest.zip.html" or create out a new project and copied the following code to your .java class file.

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;


import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;

import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;

import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;

import com.google.common.base.Preconditions;

import android.media.MediaScannerConnection;
import android.net.Uri;

import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;

import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

public class GoogleTest extends Activity {
static final int REQUEST_ACCOUNT_PICKER = 1;
 static final int REQUEST_AUTHORIZATION = 2;
 static final int CAPTURE_IMAGE = 3;

 private static Uri fileUri;
 private static Drive service;
 private GoogleAccountCredential credential;
 
 
 private static final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
 
 private static final String CLIENTSECRETS_LOCATION ="client_secrets.json";
 
 private static final String CLIENT_ID ="YOUR_CLIENT_ID";
 
 private static final String CLIENT_SECRET="YOUR_CLIENT_SECRET ";
 

 private static GoogleClientSecrets clientSecrets = null;
 private static final List<String> SCOPES = Arrays.asList(
     "https://www.googleapis.com/auth/drive.file",
     "https://www.googleapis.com/auth/userinfo.email",
     "https://www.googleapis.com/auth/userinfo.profile");
  
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_test);
credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
   startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}

@Override
 protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
   switch (requestCode) {
   case REQUEST_ACCOUNT_PICKER:
     if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
       String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
       if (accountName != null) {
         //credential.setSelectedAccountName(accountName);
         //service = getDriveService(credential);
         startCameraIntent();
        // saveFileToDrive();
       }
     }
     break;
   case REQUEST_AUTHORIZATION:
     if (resultCode == Activity.RESULT_OK) {
       saveFileToDrive();
     } else {
       startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
     }
     break;
   case CAPTURE_IMAGE:
     if (resultCode == Activity.RESULT_OK) {
       saveFileToDrive();
     }
   }
 }

 private void startCameraIntent() {
   String mediaStorageDir = Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES).getPath();
   String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
   //fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_"
   //    + timeStamp + ".jpg"));
 
   fileUri = Uri.fromFile(new java.io.File(Environment.getExternalStorageDirectory()  + "/DCIM/Camera/" + "IMG_"
    + timeStamp + ".jpg"));  
 
   
   Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
   cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
   startActivityForResult(cameraIntent, CAPTURE_IMAGE);
 }

 private void saveFileToDrive() {
final String TAG= null;
   Thread t = new Thread(new Runnable() {
    
@Override
     public void run() {
       try {
        //media scanned to each file for every new times it was created
       
        File fil=new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/");
   
    File[] Files=fil.listFiles();

     for (int count = 0 ; count < Files.length;count ++){
     File fs = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/" + Files[count].getName());
                      
                      MediaScannerConnection.scanFile(GoogleTest.this, new String[]{fs.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() {
 
  public void onScanCompleted(String path, Uri uri) {
  // TODO Auto-generated method stub
 
  }
  });
     
     
     }
       
       
        // File's binary content
       AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
      
Account[] accounts = am.getAccountsByType("com.google");
         
AccountManagerFuture<Bundle> accFut = AccountManager.get(getApplicationContext()).getAuthToken(accounts[0], "oauth2:"+"https://www.googleapis.com/auth/drive", true, null, null);
Bundle authTokenBundle;
   authTokenBundle = accFut.getResult();
final String token = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();
am.invalidateAuthToken("com.google", token);
HttpTransport httpTransport2 = new NetHttpTransport();
       
Log.d(TAG,"AuthToken: "+token);
JacksonFactory jsonFactory2 = new JacksonFactory();
Log.d(TAG,"RefreshToken 123");
//Intent intent = new Intent();
String accountname=authTokenBundle.get(AccountManager.KEY_ACCOUNT_NAME).toString();
Log.d(TAG,"Account Name : " + accountname);
   GoogleCredential credent=new GoogleCredential.Builder()
               .setTransport(new NetHttpTransport())
               .setJsonFactory(new JacksonFactory())
               .setClientSecrets(CLIENT_ID, CLIENT_SECRET)          
               .build().setAccessToken(token); 
     
          HttpTransport httpTransport = new NetHttpTransport();
        
JacksonFactory jsonFactory = new JacksonFactory();           
         
          Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, credent);
        
           final Drive drive = b.build();
          
           
           Log.d(TAG,"Drive is been build 789");
          
         java.io.File fileContent = new java.io.File(fileUri.getPath());
            // java.io.File fileContent = new java.io.File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/IMG.jpg");
         FileContent mediaContent = new FileContent("image/jpeg", fileContent);

         // File's metadata.
         com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
         body.setTitle(fileContent.getName());
         body.setMimeType("image/jpeg");

     
         com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute();
           Log.d(TAG,"File is been sent 101112");
         if (file != null) {
           showToast("Photo is uploaded to Google drive: " + file.getTitle());
           startCameraIntent();
         } 
       } catch (UserRecoverableAuthIOException e) {
         startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
       } catch (IOException e) {
         e.printStackTrace();
       } 
       catch (OperationCanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
     }
   });
   t.start();
 }
 private static GoogleClientSecrets loadClientSecrets(JsonFactory jsonFactory) throws IOException {
   if (clientSecrets == null) {
     InputStream inputStream = GoogleTest.class.getResourceAsStream(CLIENTSECRETS_LOCATION);
     Preconditions.checkNotNull(inputStream, "missing resource %s", CLIENTSECRETS_LOCATION);
     clientSecrets = GoogleClientSecrets.load(jsonFactory, inputStream);
     Preconditions.checkArgument(!clientSecrets.getDetails().getClientId().startsWith("[[")
         && !clientSecrets.getDetails().getClientSecret().startsWith("[["),
         "Please enter your client ID and secret from the Google APIs Console in %s from the "
         + "root samples directory",CLIENTSECRETS_LOCATION);
   }
   return clientSecrets;
 }

private Drive getDriveService(GoogleAccountCredential credential) {
   return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential)
       .build();
 }

 public void showToast(final String toast) {
   runOnUiThread(new Runnable() {
     @Override
     public void run() {
       Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();
     }
   });
 }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_google_test, menu);
return true;
}

}

11.Don't forget include below external Google Drive API lib into libs folder of your project location.

   


12. Last for your manifest file, you need to include four lines of below to allow access permission.

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

7 comments:

  1. PLEASE GIVE UPLOAD CODE IN JSP FOR USING IN GOOGLE APP ENGIN

    ReplyDelete
  2. Does this app uses a common drive or it will upload files to clients and client must grant access to their drive?

    ReplyDelete
  3. your link not working proper

    http://rapidgator.net/file/63338103/com.android.example.googledrivet.GoogleTest.zip.html

    ReplyDelete
  4. I want to use Keytool but i cant' see path in first image... tell me path for download keytool.

    ReplyDelete
  5. When I am trying to run this code, I am getting NullPointerException at

    final String token = authTokenBundle.get(AccountManager.KEY_AUTHTOKEN).toString();

    this line.

    ReplyDelete
  6. please can you send me all the required libraries on deeplove9493@gmail.com

    ReplyDelete
  7. sir its a file not found error

    ReplyDelete