Вы находитесь на странице: 1из 56

Connecting to Google Drive* from an Android* App

Submitted by THOMAS E. (Intel) on November 5, 2013

Share

Tweet

Share
Download source code
This sample demonstrates how to connect to an individuals Google Drive* online storage service from an Android
application. Ill 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(),
2
REQUEST_ACCOUNT_PICKER);
1

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 devices storage.
01
02
03
04
05
06
07
08
09
10

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 activitys onActivityResult 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)
02 {
03
switch (requestCode)
04
{
05

06
case RESULT_STORE_FILE:
07
mFileUri = data.getData();
08
// Save the file to Google Drive
09
saveFileToDrive();
10
break;
11
}
12
}
01

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 doesnt slow down the main UI
thread, causing the UI to become slow and laggy.
01
02
03
04
05
06
07
08

private void saveFileToDrive()


{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{

09
10
11
12

}
});
t.start();
}

Within the run function, a new URI is created based on the real path to the media files contents. This is because the
path thats associated with the URI thats returned from the Gallery Intent is a virtual path that doesnt work with the
upload feature of the Google Drive API. Here were getting the physical path and creating a new URI from it to
upload to Google Drive.
1
// Create URI from real path
2
String path;
3 path = getPathFromUri(mFileUri);
4 mFileUri = Uri.fromFile(new java.io.File(path));
5
6
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 files content to the
users Google Drive. A Files object is created from the Service object created in OnCreate, and its Insert function is
used to prepare the media files content to be uploaded. Then execute is called to actually push the content to the
Google Drive in the cloud.
1
2
3
4
5
6
7
8

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.
1 final Button button2 = (Button) findViewById(R.id.button2);
2 button2.setOnClickListener(new View.OnClickListener()
3
{
4
public void onClick(View v)
5
{
6
getDriveContents();
7
}
8
});

getDriveContents starts a new thread to download a list of file names of all the content in the Google Drive account.
1
2
3
4
5
6

private void getDriveContents()


{
Thread t = new Thread(new Runnable()
{
@Override
public void run()

7
8

{
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.
01 com.google.api.services.drive.Drive.Files f1 = mService.files();
02 com.google.api.services.drive.Drive.Files.List request = null;
03
04
do
05
{
06
try
07
{
08
request = f1.list();
09
request.setQ("trashed=false");
10
com.google.api.services.drive.model.FileList fileList = request.execute();
11
12
mResultList.addAll(fileList.getItems());
13
14
request.setPageToken(fileList.getNextPageToken());
15
} catch (UserRecoverableAuthIOException e) {
16
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
17
} catch (IOException e) {
18
e.printStackTrace();
19
if (request != null)
20
{
21
request.setPageToken(null);
22
}
23
}
24 } while (request.getPageToken() !=null && request.getPageToken().length() > 0);
25
26
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.
1 OnItemClickListener mMessageClickedHandler = new OnItemClickListener()
2 {
3
public void onItemClick(AdapterView parent, View v, int position, long id)
4
{
5
downloadItemFromList(position);
6
}
7
};

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 files contents. The files
contents are returned in the form of an InputStream.
01
02
03
04
05
06
07
08
09
10
11
12
13

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);

14
15
16

} 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).
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

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 users Google Drive accounts. For more information on the Google Drive API, please
see:https://developers.google.com/drive/v2/reference/.

Author Bio and Photo

Gideon is a member of the Intels Software and Services Group and works with
independent software vendors to help them optimize their software for Intel Atom processors. In the past he
worked on a team that wrote Linux* graphics drivers for platforms running the Android OS.

About Authorization
Every request your application sends to the Drive API must include an authorization token. The token
also identifies your application to Google.

About authorization protocols


Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are
supported. If your application uses Google Sign-In, some aspects of authorization are handled for
you.

Authorizing requests with OAuth 2.0

All requests to the Drive API must be authorized by an authenticated user.


The details of the authorization process, or "flow," for OAuth 2.0 vary somewhat depending on what
kind of application you're writing. The following general process applies to all application types:
1.

When you create your application, you register it using the Google Developers Console.
Google then provides information you'll need later, such as a client ID and a client secret.

2.

Activate the Drive API in the Google Developers Console. (If the API isn't listed in the
Developers Console, then skip this step.)

3.

When your application needs access to user data, it asks Google for a particular scope of
access.

4.

Google displays a consent screen to the user, asking them to authorize your application to
request some of their data.

5.

If the user approves, then Google gives your application a short-lived access token.

6.

Your application requests user data, attaching the access token to the request.

7.

If Google determines that your request and the token are valid, it returns the requested data.
Some flows include additional steps, such as using refresh tokens to acquire new access tokens.
For detailed information about flows for various types of applications, see Google's OAuth 2.0
documentation.
Here's the OAuth 2.0 scope information for the Drive API:
Scope

Meaning

https://www.googleapis.com/auth/drive

Full, permissive scope to access all of a user's


files. Request this scope only when it is strictly
necessary.

https://www.googleapis.com/auth/drive.readonly

Allows read-only access to file metadata and f


content

https://www.googleapis.com/auth/drive.appfolder

Allows access to the Application Data folder

https://www.googleapis.com/auth/drive.file

Per-file access to files created or opened by th


app

https://www.googleapis.com/auth/drive.install

Special scope used to let users approve


installation of an app.

https://www.googleapis.com/auth/drive.metadata

Allows read-write access to file metadata, but


does not allow any access to read, download,
write or upload file content. Does not support f

creation, trashing or deletion. Also does not al


changing folders or sharing in order to prevent
access escalation.
https://www.googleapis.com/auth/drive.metadata.readonly

Allows read-only access to file metadata, but


does not allow any access to read or downloa
file content

https://www.googleapis.com/auth/drive.photos.readonly

Allows read-only access to all photos.


The spaces parameter must be set to photo

https://www.googleapis.com/auth/drive.scripts

Allows access to Apps Script files

If your app requires access to any other Google APIs, you can add those scopes as well. For more
information about Google API scopes, see Using OAuth 2.0 to Access Google APIs.

What scope or scopes


What scope or scopes does my app need?

As a general rule, choose the most restrictive scope possible, and avoid requesting scopes that your
app does not actually need. Users more readily grant access to limited, clearly described scopes.
Conversely, users may hesitate to grant broad access to their files unless they truly trust your app
and understand why it needs the information.
The scope https://www.googleapis.com/auth/drive.file strikes this balance in a practical way.
Presumably, users only open or create a file with an app that they trust, for reasons they understand.

Requesting full drive scope for an app


Full access to all files in the user's Drive (https://www.googleapis.com/auth/drive) may be
necessary for some apps. An app designed to sync files, for instance, needs this level of access to
Drive. Apps with special needs related to listing or reorganizing files might need full scope.

Requesting drive-wide read-only scope for an app


Read-only access to all of a user's Drive files (https://www.googleapis.com/auth/drive.readonly)
may be useful for certain apps. For instance, a photo browser might need to reorganize image files in
a unique presentation order for a slideshow, or a mobile app might have to work around unique

display constraints without needing to write anything. For apps that only need to read file metadata for
all files in Drive, there'shttps://www.googleapis.com/auth/drive.metadata.readonly.

Requesting full drive scope during app development


One common and completely valid case for using full scope is iterative development. It may just be
easier to avoid authorization-related constraints and use the full scope while testing your app during
development. Then before you actually publish your app, you can back off to the file-level scope or
whatever scope you really need for production operation.
To request access using OAuth 2.0, your application needs the scope information, as well as
information that Google supplies when you register your application (such as the client ID and the
client secret).
Tip: The Google APIs client libraries can handle some of the authorization process for you. They are available for a
variety of programming languages; check the page with libraries and samples for more details.

Perform Google Apps Domain-Wide Delegation of Authority

In enterprise applications you may want to programmatically access users data without any manual
authorization on their part. In Google Apps domains, the domain administrator can grant to third party
applications domain-wide access to its users' data this is referred as domain-wide delegation of
authority. To delegate authority this way, domain administrators can use service accounts with OAuth
2.0.
Note: Owning many widely shared documents in the same corpus can have severe performance
implications. Service accounts can become extremely slow if they own many widely-shared items.
Using service accounts as common owner for domain-wide files is strongly discouraged.
Note: Service accounts are limited to the default number of requests/day and requests/second/user
for free accounts. They do not have the same quotas as your application.
For additional detailed information, see Using OAuth 2.0 for Server to Server Applications
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and
code samples are licensed under the Apache 2.0 License. For details, see our Site Policies.
Last updated January 16, 2016.

Enable the Drive Platform


To get started integrating with the Drive UI, you need to enable the Drive API and provide
configuration details in your API project. This gives you access to the API as well as access to UI
integration features.
Enable the Drive API

To interact with the Drive API, you need to enable the Drive API service for your app. You can do this
in the Google API project for the app.
To enable the Drive API, complete these steps:
1.

Go to the Google Developers Console.

2.

Select a project.

3.

In the sidebar on the left, expand APIs & auth and select APIs.

4.

In the displayed list of available APIs, click the link for the Drive API and click Enable API.

5.

Within the Drive API page, select the Drive UI Integration tab and begin configuring how your App will
integrate with the Drive UI.
Configure your App's Drive UI Integration

Configuring your App's Drive UI Integration requires you to provide detailed developer information for
your app. To begin configuring, navigate to the Drive UI Integration tab within the Drive API page.
Note: You must provide this detailed information if you want Drive UI integration for your app, or if you are
going to list your app on the Chrome Web Store.

Drive Integration Configuration


This section contains fields to enter information describing your application. The Application
Name and Short Description fields are displayed to users in the Manage apps dialog in the Drive
UI. The Long Description field can be used to describe your application in more detail.

Icons
Specify application and document icons to display in Google Drive. For more information on the
requirements for these assets, see the Branding Guidelines.

Drive Integration
In this section, you'll need to specify the Open URL for your app, and your preferences on how users
create and open files with the app. Also, you can select from optional features like support for multiple
file selection and Google doc import.

Authentication
Warning: Do not select Automatically show OAuth 2.0 consent screen when users open my application from
Google Drive. This feature is deprecated. All authorization requests must be initiated by the application.

Install URL
You can use the Install URL if you wish to redirect your users to a special URL the first time they
open your app from Drive.

Open URL
There are two important things to keep in mind for the Open URL:

Make sure you give a fully qualified domain name for Open URL, localhost does not work.

The URL must belong to you. After the app registration is complete, you will need to verify your
ownership of this URL in order to create a Chrome Web Store listing. For more information, see Site
Verification

Open URLs may include the template variable placeholders:

Variable Placeholder

Description

{ids}

A comma-separated list of file IDs that are being opened.

{exportIds}

A comma-separated list of file IDs that are being exported.

{userId}

The profile ID that uniquely identifies the user.

{action}

The action being performed. Either: open or create

If no template variables are used in the Open URL, a state query parameter is automatically
appended. It contains a JSON encoded string of all the above template variables. You may choose to
use either the statequery parameter or URL template variable substitution.
See Open Files for more information on handling file open actions.

Setting MIME types and file extensions


Specify the MIME types and file extensions your app can open. When entering these values, consider
the following:

Specify both MIME types and file extensions. There are cases where just one or the other is not
sufficient.

Make sure the MIME types you enter are standard, canonical types or Google MIME types, free of
typos or misspellings.

Consider carefully whether your app needs default or secondary status.

Default vs. Secondary status is related to opening files with your app by default. Simply put, default
types are the MIME types and file extensions you really want your app to open by default (the user
makes the final choice on this). Secondary types are ones that your app can open. For example, an
image editor might need to list numerous secondary types to open (png, jpg, and so on) but few
default types, which might include only its native format for layering and editing images.
When multiple installed apps are registered as the default type for a particular MIME type or file
extension, the last-installed app acts as default until the user makes a specific selection.
Note: If you only need to let Google Drive users open shortcuts to files not actually stored in Drive, you can
leave the MIME types blank.

Creating files
You can control whether or not users can create new Drive files with your application by checking
the Allow users to create new documents using this application option. If enabled, you must provide
a New URL that users are redirected to when a user selects your application from the New menu in
Drive. You can optionally fill in theDocument Name field to provide a name for the type of document
your application creates. This is displayed in the Create New menu in Drive.

Multiple file support


If your application supports opening multiple files in a single instance, you can check this option to
enable multiple file support. Otherwise, each time a user opens a file a new instance of your
application is spawned.

Importing
You can opt to import files and convert them into formats supported by your app. For more
information, see Open and convert Google Docs in your app.

Mobile browser support


Select this option if your application can be used in a mobile browser.
Next steps

After you have enabled the Drive API and filled out the Drive UI Integration tab, you'll need users -or a test account for development -- to install your app.
Except as otherwise

Install Your App


Google Drive lets users install an app by approving an OAuth 2.0 access request. To prompt users for
installation, apps can request the
scope https://www.googleapis.com/auth/drive.install. Users see a dialog like this:

Whenever possible, it's best to request all the Drive scopes an app needs at the same time you
request approval to install. This avoids the need to present multiple OAuth dialogs to the user. In
order to meet authorization requirements and have basic file access after installation, an app would
request these scopes:
https://www.googleapis.com/auth/drive.install
https://www.googleapis.com/auth/drive.file
profile

When users approve these scopes, the app is installed for the user, with access to files that the user
creates or opens with the app. See Choose auth scopes and Authorizing Your App with Google
Drive for more information about scopes you can request for Drive apps, and how to request them.
Note: If you opt to Create a Chrome Web Store Listing, users can also install your app from Chrome
Web Store.

Next steps
An installed app needs to be able to handle create and open actions launched from the Drive UI.
See Create Filesor Open Files to learn more.

Create Files
By responding to actions launched from the prominent Create button in the Google Drive UI, apps
can create Drive files as well as shortcuts to files stored outside of Drive. To see what the UI options
look like, read the overviewWhat Can You do with the Drive platform?.

Create a new file from the Drive UI


When a user selects Create > More in Google Drive, they'll see applications that have registered a
URL for creating files. Then, when the user selects an app from the menu list, Drive redirects the user
to that app's Open URL (this URL is defined when you enable the Drive platform).
The redirected request from the user's browser contains the following important information in
the stateparameter:

The action, set to create.

The folderId, which identifies the parent folder.

The userId, which identifies the authenticated user.


Instead of the state parameter, you may opt to use template variable substitution to construct the
request URL instead.
The state parameter is URL-encoded, so you'll need to handle the escape characters and parse it as
JSON. In JSON notation, state information from a "create" URL looks like the following:
{
"action":"create",
"folderId":"0ADK06pfg",
"userId":"103354693083460731603"
}

Apps can detect the create value in the state parameter to verify that this is a request to create a
new file.
For guidance on uploading the new file's metadata and content to Drive, see examples and reference
information for the files.create method.

Create a shortcut to a file

To create a shortcut instead of a file stored in Drive, use the files.create method of the API and
make sure you set the MIME type application/vnd.google-apps.drive-sdk. Do not upload any
content when creating the file.
JAVAPYTHONPHP.NETRUBYNODE.JS
File fileMetadata = new File();
fileMetadata.setName("Project plan");
fileMetadata.setMimeType("application/vnd.google-apps.drive-sdk");
File file = driveService.files().create(fileMetadata)
.setFields("id")
.execute();
System.out.println("File ID: " + file.getId());

When updating shortcuts, you can use files.update to set the modifiedTime of the file. This ensures it
displays and is sorted properly in the Drive UI.
JAVAPYTHONPHP.NETRUBYNODE.JS
String fileId = "1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ";
File fileMetadata = new File();
fileMetadata.setModifiedTime(new DateTime(System.currentTimeMillis()));
File file = driveService.files().update(fileId, fileMetadata)
.setFields("id, modifiedTime")
.execute();
System.out.println("Modified time: " + file.getModifiedTime());

Adding custom thumbnails and indexable text


To increase the discoverability of files associated with shortcuts, you can upload both thumbnail
images and indexable text when inserting or modifying the file metadata. For more information,
see Manage File Metadata.
Except as otherwise noted, the co

Open Files
The Google Drive UI provides two ways to open files:

The Open with contextual menu item

The Google Picker dialog for opening files

To see what these UI features look like, check the overview of What Can You Do with the Drive
platform?. The rest of this page describes how to integrate your app with these Drive UI features to
open files stored in Google Drive.
Open files using the Open with contextual menu

When a user chooses files in Google Drive and selects the Open with menu option, Drive redirects
the user to theOpen URL for the selected application (this URL is defined when you enable the Drive
platform). The redirected request from the user's browser contains this important information in
the state parameter:

The ids of the file(s) to open (or exportIds when opening native Google documents)

The action, set to open.

The userId of the authenticated user.

Instead of the state parameter, you may opt to use template variable substitution to construct the
request URL instead.
You'll need the file ID to fetch file metadata and download file content. The state parameter is URLencoded, so you'll need to handle the escape characters and parse it as JSON. In JSON notation,
state information for an Open with URL looks like the following:
{
"ids": ["0Bz0bd"],
"action":"open",
"userId":"103354693083460731603"
}

Once it has the file ID and an access token, an app can check permissions, fetch the file metadata,
and download the file content as described in the reference documentation for files.get.

Note: All apps, including apps opening files from shortcuts, should call files.get to check the user's permissions
for a document. Apps should warn read-only users when they are opening a file they cannot edit or save
(instead of letting them spend time editing, and then giving an error on save).

Open and convert Google Docs in your app


An app registered with the Import option enabled in the Drive UI Integration tab within the Drive API
in the Developers Console can import supported Google Doc formats. This means that if a user
selects Open with for a Google doc, the app can convert it to a format that the app can handle.
When Open with triggers a conversion this way, Drive evaluates the MIME types an app can open
(set during registration) and extrapolates the list of formats that the app can import.
Google Doc formats and supported export MIME types map to each other as follows:
Google Doc Format

Conversion Format

Corresponding MIME type

Documents

HTML

text/html

Plain text

text/plain

Rich text

application/rtf

Open Office doc

application/vnd.oasis.opendocument.text

PDF

application/pdf

MS Word document

application/vnd.openxmlformats-officedocument.wordprocessingml.docume

MS Excel

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Open Office sheet

application/x-vnd.oasis.opendocument.spreadsheet

PDF

application/pdf

CSV (first sheet only)

text/csv

JPEG

image/jpeg

Spreadsheets

Drawings

Google Doc Format

Presentations

Apps Scripts

Conversion Format

Corresponding MIME type

PNG

image/png

SVG

image/svg+xml

PDF

application/pdf

MS PowerPoint

application/vnd.openxmlformats-officedocument.presentationml.presentatio

PDF

application/pdf

Plain text

text/plain

JSON

application/vnd.google-apps.script+json

When a user selects an app from the Open with contextual menu for a Google Doc, Drive redirects
the user to the Open URL for the selected application. The redirected request from the user's browser
contains this important information in the state parameter:

The action, set to open.

The exportIds to use.


Note: If the user has multi-selected both Google docs and other document types, the state parameter may
include both file IDs and export IDs.

Once it has the export IDs, an app can fetch the file metadata to determine the mime type if
necessary.
The app can also download the converted file content with the files.export method.
JAVAPYTHONPHP.NETRUBYNODE.JS
String fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().export(fileId, "application/pdf")
.executeMediaAndDownloadTo(outputStream);

Apps should display converted files as read-only, or let users save them as new files.

Open and upload files using the Google Picker API

If you want to let users open or upload Google Drive files directly from your web app independently of
the Drive UI, you can use the Google Picker API. The picker can display a list of the currently
authenticated user's Drive files in an interface like the following:

.
When a user selects a file from the list, the file ID is returned, and the ID may be used by your app to
access the file. You can also add to a picker dialog the capability to upload files to Google Drive.
The following picker example illustrates an image selector/uploader page that could be opened from
an Open or Upload Drive files button in a web app. This example demonstrates how to set
the AppId value, and incorporates some useful picker features such as enabling multi-select, hiding
the navigation pane, and choosing the user account with the app's current OAuth 2.0 token:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Picker Example</title>
<script type="text/javascript">
// The Browser API key obtained from the Google Developers Console.
// Replace with your own Browser API key, or your own key.
var developerKey = 'xxxxxxxYYYYYYYY-12345678';
// The Client ID obtained from the Google Developers Console. Replace with your
own Client ID.
var clientId = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
// Replace with your own App ID. (Its the first number in your Client ID)
var appId = "1234567890";
// Scope to use to access user's Drive items.
var scope = ['https://www.googleapis.com/auth/drive'];
var pickerApiLoaded = false;
var oauthToken;
// Use the Google API Loader script to load the google.picker script.
function loadPicker() {
gapi.load('auth', {'callback': onAuthApiLoad});
gapi.load('picker', {'callback': onPickerApiLoad});
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': false
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {

oauthToken = authResult.access_token;
createPicker();
}
}
// Create and render a Picker object for searching images.
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(oauthToken)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(developerKey)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
// A simple callback implementation.
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
var fileId = data.docs[0].id;
alert('The user selected: ' + fileId);
}
}
</script>
</head>
<body>
<div id="result"></div>
<!-- The Google API Loader script. -->
<script type="text/javascript" src="https://apis.google.com/js/api.js?
onload=loadPicker"></script>
</body>
</html>

The AppId set here and the client ID used for authorizing access to a user's files must be contained in
the same app. Within the Developers Console, AppId can be identified as the "Project Number" on
the Project Dashboard, or as the first number in the client ID.

Important:The setOAuthToken function allows an app to use the current auth token to determine which Google
account the picker uses to display the files. If a user is signed into multiple Google accounts, this allows the picker to
display the files of the appropriate authorized account.

After obtaining the file ID from the picker when opening files, an application can then fetch the file
metadata and download the file content as described in the reference documentation for files.get.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and
code samples are licensed under the Apache 2.0 License. For details, see our Site Policies.
Last updated January 16, 2016.

Access to Google Drive from self implemented


Android application

up
vote0dow
n vote
2
favorite

My Problem is, that I want to use any SDK or API to access my google drive from my android
phone without using an existing google drive app on my android phone.
I read the instructions on this side: google drive sdk The code examples does only work for desktop
applications and the "integrate with Android" topic on the side does not provide any example how I can
access my google drive from my android application.
I already read android-api-for-google-drive here but this leads only to more links and how-to's which are
far to complicated and fuzzy.
Has anyone experience with connecting to google-drive from an android application and could
help with any example code or "clean-and-short-explained" tutorial?
android

google-drive-sdk

shareimprove this question

asked Sep 23 '12 at 22:10

Jan Koester
733615

"...the "integrate with Android" topic on the side does not provide any example how I can access my google
drive from my android application." - Urrrm, it actually goes quite a long way to explaining it with example
manifest and Activity. What have you tried so far? Squonk Sep 23 '12 at 22:31
The example code in the "integrate with Android" article is for the use case that I choose a file in my android device
and then the user has the choice to select the Activity to .I want to send a file from my app to the google drive directly,
so I can for example send an image, which I have drawn in my app to my google drive account Jan Koester Sep 23
'12 at 23:20
See the Files.insert API. developers.google.com/drive/v2/reference/files/insert Squonk Sep 24 '12 at 1:00
add a comment

1 Answer
activeoldestvotes

up
vote3dow
n vote
accept ed

Luckily, just after you asked this question, Google released their Play Services (see this link), which
makes it a heck of a lot easier to access files using the Drive SDK & Drive API. Please see my post on
Google Plus that gives a step-by-step walkthrough and code example on how to integrate an Android
app with Google Drive
documents:https://plus.google.com/u/0/114042449736049687152/posts/CD3L8zcJg5Z
In the tutorial, I reference a particular Google IO 2012 talk (slides
athttps://docs.google.com/presentation/d/1LrEKp2PqESsES3upS1xsSARz35KS9QHnYFTKvS2yzM/preview#slide=id.p19), but please read my G+ post because I go through the
various flaws, pitfalls, and omitted details from this presentation.
Before you start coding anything, get yourself signed up for the Google APIs (see this link), get into the
API Console, and turn on both the Google Drive API and Drive SDK.
Good luck & have fun!
shareimprove this answer

edited Jun 16 '15 at 12:36

answered Oct 15 '12 at 3:23

this is great! T

David

Stephen Wylie

2,44921935

66157

How to Use Google Drive Offline on a Deskop or Mobile Device

If theres any drawback to using cloud-based services for all your productivity and organization needs, its that
if you cant get an Internet connection, youre basically out of luck.
Thankfully, however, the engineers at Google have thought of a way around this problem and created a setting
which will enable you to use their Drive apps and management tools 100 percent offline.
From the Desktop
If youre like me, the main place you find yourself booting up Google Drive every day is from your desktop or
laptop. To activate the offline setting on your main PC or Mac, youll need to start by downloading Googles
Drive app for your respective operating system, located here.

Once Drive is installed, you need to sign in on the account that you want to use offline files with. After the signin operation is complete, the app will automatically begin syncing your available files to the desktop, and any
that have been brought in from the cloud will immediately be available for full local access and offline editing
rights.

If you dont want to sync the entirety of your library all at once, you can alter which files or folders are saved by
clicking the Drive taskbar icon, and then selecting Preferences from the following menu.

The first section of the Preferences page will give you the option to either sync Everything in My Drive, or
Only These Folders.

Select the second choice, and scroll through to either enable or disable any files or folders you want attached
to your current desktop.
From the Chrome Browser or a Chromebook
RELATED ARTICLE

HTG Explains: Should You Buy a Chromebook?


Chromebooks are becoming more and more popular, with recent reports indicating that Chromebooks captured about
10% of all desktop, notebook,... [Read Article]

If you want to make offline files work without downloading an extra program on your PC, the same effect as
above can also be achieved through Googles flagship Internet browser: Chrome. Once Chrome is installed
(download link here), youre going to need to find the Google Drive application in the Chrome app store.

After this is ready (the button should say Visit Website in green if the setup was successful), log in to your
preferred Google Drive account. When youre ready to start the syncing process, simply find the Settings
button in the main Drive hub, and bring up the menu highlighted above.
Click the box to enable Google Drive to Sync Google Docs, Sheets, Slides & Drawings, at which point your
computer will begin the process of downloading local versions of every document or picture stored on the
linked account.

Once these are pulled down, youll be able to freely edit and save any file without a connection to the Internet.
If you want to disable Offline syncing directly from Chrome or your Chromebook, get back into the Drive main
page, and then click the menu on the side. Scroll down to settings, where youll see the option for Offline
sync.

Once you click this youll be taken to a secondary confirmation window, where youll need to click Disable
Offline one last time. Keep in mind that this option will un-sync all your files at once, rather than the one-byone method mentioned in the previous section.

From Your Mobile Device


RELATED ARTICLE
How to Save Drive Space by Offloading Local Files to the Cloud
If youre thinking about buying a new hard drive because youre running out of capacity, you can quickly free up... [Read
Article]

If youre someone who finds yourself on the road with a WiFi-only tablet or spotty cell service from your phone,
Google Drive can also function as an app for both the iOS and Android ecosystems that allows you to edit
documents offline.
To do this, first youll need to open up the app on your mobile device and find the file you want to sync offline.
In order to save space and prevent a phone or tablet from going into download overload, Drive for mobile will
only allow you to sync documents or spreadsheets for offline use on a file-by-file basis.

Once you find the file you want to work on, tap the button next to it which looks like three gray circles stacked
on top of one another.

Here youll see the option to Keep offline in the submenu. Click on this, and the Google Drive app will notify
you as soon as your file is ready to go!

If youre looking to replace a suite of apps like Microsoft Office on the cheap, the offline version of Google
Drive is a quick, light, and free option that provides enough functionality and flexibility to keep any productivity
pioneer working through the worst of Internet outages.

JOIN THE DISCUSSION (2 REPLIES)


Chris Stobing is a writer and blogger from the heart of Silicon Valley. Raised around tech from birth, he's had an interest in PC hardware
and networking technology for years, and has come to How-to-Geek to contribute his knowledge on both. You can follow him on Twitter
here.

Published 08/31/15

FROM THE WEB

how to upload file at google drive in android when i


implement throght it gallery

up
vote0dow
n vote
favorite

i am working on google drive and try to intrgate in my app.lots of thing i have done. first i craete SH1
key and then enable the drive api and then genrate the APP key.now i have implement this link but when
i pick the image from gallery it redirect back on this activity and i print the path of image it gives correct
path and doesn't uploading. what i do now??please anybody help me i m struck here what i do now
cannot understand.
https://developers.google.com/drive/quickstart-android#step_4_set_up_the_sample

import java.io.IOException;
import
import
import
import
import
import
import
import
import
import
import
import
import

android.accounts.AccountManager;
android.app.Activity;
android.content.Intent;
android.database.Cursor;
android.net.Uri;
android.os.Bundle;
android.provider.MediaStore;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.ImageView;
android.widget.TextView;
android.widget.Toast;

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.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOExceptio
n;
import com.google.api.client.http.FileContent;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;

import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
public class MainActivity extends Activity{
private static final int REQUEST_ACCOUNT_PICKER = 1;
private static final int SELECT_PICTURE = 3;
private static final int REQUEST_AUTHORIZATION = 2;
private static Drive service;
private GoogleAccountCredential credential;
private static Uri selectedImageUri;
private String selectedImagePath;
private ImageView img;
private TextView tv;
Intent pictureintent;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// img = (ImageView)findViewById(R.id.ImageView01);
((Button) findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
pictureintent = new Intent();
pictureintent.setType("image/jpeg");
pictureintent.setAction(Intent.ACTION_GET_CONTENT);
pictureintent.putExtra(MediaStore.EXTRA_OUTPUT, selectedImageUri);
startActivityForResult(pictureintent, SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, 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);
saveFileToDrive();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
saveFileToDrive();
} else {
startActivityForResult(credential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
case SELECT_PICTURE:
if (resultCode == Activity.RESULT_OK) {

selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
// tv = (TextView) findViewById(R.id.text1);
//tv.setText("File Path: " + selectedImagePath);
showToast("File Path: " + selectedImagePath);
System.out.println("Image Path : " + selectedImagePath);
//img.setImageURI(selectedImageUri);
startpictureIntent();
}
}
}

private Drive getDriveService(GoogleAccountCredential credential) {


return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(),
credential)
.build();
}
public void startpictureIntent(){
credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}

private void saveFileToDrive() {


Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
// File's binary content
java.io.File fileContent = new java.io.File(selectedImageUri.getPath());
FileContent mediaContent = new FileContent("image/jpeg", fileContent);
// File's metadata.
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType("image/jpeg");
File file = service.files().insert(body, mediaContent).execute();
if(file != null) {
showToast("Photo uploaded: " + file.getTitle());
}
}catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}

}
});
t.start();
}

public String getPath(Uri uri) {


String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null,
null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}

public void showToast(final String toast) {


runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_LONG).show();
}
});
}
}
android

google-drive-sdk

shareimprove this question

google-drive-realtime-api
edited Sep 18 '13 at 14:50

asked Sep 11 '13 at 7:19

Adam Lear

Jelly Bean

19.4k85484

1419

add a comment

1 Answer
activeoldestvotes

up
vote0dow
n vote

I too use almost the same code for uploading a pdf file, but it is working for me,
try
{

FileContent mediaContent = new FileContent("application/pdf",pdfFile);


com.google.api.services.drive.model.File body = new
com.google.api.services.drive.model.File();
body.setTitle(filename);
body.setMimeType("application/pdf");
com.google.api.services.drive.model.File file =
servicer.files().insert(body,mediaContent).execute();
if (file != null)
{
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast toast = Toast.makeText(getApplicationContext(), "File exported

successfully", 2000);
toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 30);
toast.show();
}
);

}
}
catch (UserRecoverableAuthIOException e)
{
startActivityForResult(e.getIntent(),REQUEST_AUTHORIZATION);
}
catch (IOException e)
{
e.printStackTrace();
}
shareimprove this answer

answered Sep 11 '13 at 9:52

Sreedhu Madhu
589519

show me fulll code please Jelly Bean Sep 11 '13 at 10:27


add a comment

Your Answer

Security Exception with Google Drive and


ACTION_GET_CONTENT

up
vote3dow
n vote

In my app users may import sounds, videos, images and other files. The import is done using standard
Intents, and the result handed in OnActivityResult

favorite

I am experiencing a security exception when trying to import files from Google Drive on my 4.2.2
tablet, files from other sources such as Dropbox, Onedrive, Gallery etc are all working OK. Importing
from Drive works fine on my 4.4 tablet.
The intent code looks like this:
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, getString(R.string.title_dialog_selectphoto)),
SELECT_PICTURE_REQUEST);
Then in my importPhotoFromUri(uri) method I try to open the uri as an inputStream:
...
InputStream is;
try {

is = getContentResolver().openInputStream(uri);
....

At which point I get a Security Exception:


java.lang.SecurityException: Permission Denial: opening provider
com.google.android.apps.docs.sync.filemanager.FileProvider
from ProcessRecord{216d9060 18832:com.app.app/u0a10153}
(pid=18832, uid=10153) that is not exported from uid 10179

I've found a few posts that seem to refer to a similar problem from a while ago:
Google Drive + ACTION_GET_CONTENT
File View from Google Drive Android Intent
https://productforums.google.com/forum/#!topic/drive/siSKHXdE-ao/discussion
But none of these appear to have a solution, other than perhaps re-implementing the Google Drive
Integration myself using their API. I'd rather avoid that and keep the user experience simple though.
From the exception tracking in my Google Analytics it looks as though this issue primarily affects users
running 4.2.2 devices, I see only 3 security exceptions from other Android versions. I also see virtually
no Security Exceptions prior to May 9th (2014), which is also the date that user igorcard made his
comment asking about the same exception on this
answer:http://stackoverflow.com/a/18298298/2214992
The last update to the Google Drive App on my 4.2.2 device was on the 8th May
I've also been able to observe the same problem in other apps, by trying to load images from my Drive,
not just in my own app.
My question then is, can I implement the drive integration another way, without dramatically changing
the User Experience, or am I left with just handling the exception and putting up an apologetic Alert
Dialog? Also, has this been broken by the recent update to Drive app or are the timings of the Drive
update and the occurrences of this exception in my analytics just coincidental?
android

shareimprove this question

asked Jun 2 '14 at 13:04

Mike Fosker
302310

It looks like this was just a bug with version 1.3.144.17. They seemed to have fixed it (probably a manifest change) in
the latest version 1.3.222.29 which was released on June 18th 2014. Tony Chan Jun 23 '14 at 21:48
1 Yes, I'm seeing the same thing. At least I learnt a lot about Drive SDK these last two weeks Mike FoskerJun 24 '14 at
14:10
add a comment

1 Answer
activeoldestvotes

up
vote0dow
n vote
accept ed

I had the same problem. The exception is thrown because there is an export false in Google drive
manifest to manage the get content intent. It's unreliable to use it. At the end I used Google Drive API
and in detail you can see newOpenFileActivityBuilder() method an example docs
shareimprove this answer

answered Jun 2 '14 at 13:09

greywolf82
6,22161837

Thanks, I was hoping to avoid that so that I can keep the simple chooser menu for users to import files from all
available places such as Dropbox, Gallery, etc. Mike Fosker Jun 3 '14 at 9:42
I can understand. I had exactly the same problem, if you want a reliable approach you have to implement that. However
it's not really complicated even if it's more code than a simple intent. greywolf82 Jun 3 '14 at 16:24
I've sort of followed your advice, and added a bit. Using this tutorial I made a custom intent chooser which I show only
on devices where the Drive FileProvider is not exported. This chooser then uses Drive SDK and
newOpenFileActivityBuilder() as suggested. Mike Fosker Jun 18 '14 at 15:42
Accept the response please if it's ok for you greywolf82 Jun 18 '14 at 16:51
add a comment

Your Answer

Implementing Server-Side Authorization


Requests to the Drive API must be authorized using OAuth 2.0 credentials. You should use server-side flow
when your application needs to access Google APIs on behalf of the user such as when the user is offline. This
approach requires passing a one-time authorization code from your client to your server that is used to acquire
an access and refresh tokens for your server.
If your application does not require offline access to user data, consider using the client-side authorization flow,
which can be implemented using only JavaScript and HTML.
Create a client ID and client secret

To get started using Drive API, you need to first create or select a project in the Google Developers Console and
enable the API. Using this link guides you through the process and activates the Drive API automatically.
Alternatively, you can activate the Drive API yourself in the Developers Console by doing the following:
1.

Open the Credentials page.

In either case, you end up on the Credentials page and can create your project's credentials from here.
From the Credentials page, click Add credentials > OAuth 2.0 client ID to create your OAuth 2.0 credentials
orAdd credentials > Service account to create a service account.
Next, if you created an OAuth 2.0 client ID, select your application type.
Your application's client IDs are now listed. You can click each client ID for details; parameters vary depending
on the ID type, but might include email address, client secret, JavaScript origins, and redirect URIs.
Take note of the Client ID as you'll need to add it to your code later.
Handling authorization requests

When a user loads your application for the first time, they are presented with a dialog to grant permission for
your application to access their Google Drive account with the requested permission scopes. After this initial
authorization, the user is only presented with the permission dialog if your app's client ID changes or the
requested scopes have changed.

Authenticate the user


This initial sign-in returns an authorization result object that contains an authorization code if successful.

Exchange the authorization code for an access token


The authorization code is a one-time code that your server can exchange for an access token. This access token
is passed to the Google Drive API to grant your application access to user data for a limited time.
If your application requires offline access, the first time your app exchanges the authorization code, it also
receives a refresh token that it uses to receive a new access token after a previous token has expired. Your
application stores this refresh token (generally in a database on your server) for later use.
Important: Always store user refresh tokens. If your application needs a new refresh token it
must send a request with the approval_prompt query parameter set to force. This will cause the
user to see a dialog to grant permission to your application again.

The following code samples demonstrate exchanging an authorization code for an access token
with offlineaccess and storing the refresh token.
JAVAPYTHONPHP.NET
Replace CLIENTSECRET_LOCATION value with the location of your client_secret.json file.
Note: For more information about the OAuth 2.0 package, see OAuth2 API.
import
import
import
import
import
import
import
import
import
import

com.google.api.client.auth.oauth2.Credential;
com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
com.google.api.client.http.HttpTransport;
com.google.api.client.http.javanet.NetHttpTransport;
com.google.api.client.json.jackson2.JacksonFactory;
com.google.api.services.oauth2.Oauth2;
com.google.api.services.oauth2.model.Userinfoplus;

import
import
import
import
import

java.io.IOException;
java.io.InputStream;
java.io.InputStreamReader;
java.util.Arrays;
java.util.List;

// ...
class MyClass {

// Path to client_secret.json which should contain a JSON document such as:


//
{
//
"web": {
//
"client_id": "[[YOUR_CLIENT_ID]]",
//
"client_secret": "[[YOUR_CLIENT_SECRET]]",
//
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
//
"token_uri": "https://accounts.google.com/o/oauth2/token"
//
}
//
}
private static final String CLIENTSECRET_LOCATION = "/client_secret.json";
private static final String APPLICATION_NAME = "Your app name";
private static final String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
private static final List<String> SCOPES = Arrays.asList(
"https://www.googleapis.com/auth/drive.file",
"email",
"profile");
private static GoogleAuthorizationCodeFlow flow = null;
private static final JacksonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/**
* Exception thrown when an error occurred while retrieving credentials.
*/
public static class GetCredentialsException extends Exception {
protected String authorizationUrl;
/**
* Construct a GetCredentialsException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public GetCredentialsException(String authorizationUrl) {
this.authorizationUrl = authorizationUrl;
}
/**
* Set the authorization URL.
*/
public void setAuthorizationUrl(String authorizationUrl) {
this.authorizationUrl = authorizationUrl;
}
/**
* @return the authorizationUrl

*/
public String getAuthorizationUrl() {
return authorizationUrl;
}
}
/**
* Exception thrown when a code exchange has failed.
*/
public static class CodeExchangeException extends GetCredentialsException {
/**
* Construct a CodeExchangeException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public CodeExchangeException(String authorizationUrl) {
super(authorizationUrl);
}
}
/**
* Exception thrown when no refresh token has been found.
*/
public static class NoRefreshTokenException extends GetCredentialsException {
/**
* Construct a NoRefreshTokenException.
*
* @param authorizationUrl The authorization URL to redirect the user to.
*/
public NoRefreshTokenException(String authorizationUrl) {
super(authorizationUrl);
}
}
/**
* Exception thrown when no user ID could be retrieved.
*/
private static class NoUserIdException extends Exception {
}
/**
* Retrieved stored credentials for the provided user ID.
*
* @param userId User's ID.
* @return Stored Credential if found, {@code null} otherwise.
*/
static Credential getStoredCredentials(String userId) {
// TODO: Implement this method to work with your database. Instantiate a new

// Credential instance with stored accessToken and refreshToken.


throw new UnsupportedOperationException();
}
/**
* Store OAuth 2.0 credentials in the application's database.
*
* @param userId User's ID.
* @param credentials The OAuth 2.0 credentials to store.
*/
static void storeCredentials(String userId, Credential credentials) {
// TODO: Implement this method to work with your database.
// Store the credentials.getAccessToken() and credentials.getRefreshToken()
// string values in your database.
throw new UnsupportedOperationException();
}
/**
* Build an authorization flow and store it as a static class attribute.
*
* @return GoogleAuthorizationCodeFlow instance.
* @throws IOException Unable to load client_secret.json.
*/
static GoogleAuthorizationCodeFlow getFlow() throws IOException {
if (flow == null) {
InputStream in =
MyClass.class.getResourceAsStream(CLIENTSECRET_LOCATION);
GoogleClientSecrets clientSecret =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecret, SCOPES)
.setAccessType("offline")
.setApprovalPrompt("force")
.build();
}
return flow;
}
/**
* Exchange an authorization code for OAuth 2.0 credentials.
*
* @param authorizationCode Authorization code to exchange for OAuth 2.0
*
credentials.
* @return OAuth 2.0 credentials.
* @throws CodeExchangeException An error occurred.
*/
static Credential exchangeCode(String authorizationCode)
throws CodeExchangeException {

try {
GoogleAuthorizationCodeFlow flow = getFlow();
GoogleTokenResponse response = flow
.newTokenRequest(authorizationCode)
.setRedirectUri(REDIRECT_URI)
.execute();
return flow.createAndStoreCredential(response, null);
} catch (IOException e) {
System.err.println("An error occurred: " + e);
throw new CodeExchangeException(null);
}
}
/**
* Send a request to the UserInfo API to retrieve the user's information.
*
* @param credentials OAuth 2.0 credentials to authorize the request.
* @return User's information.
* @throws NoUserIdException An error occurred.
*/
static Userinfoplus getUserInfo(Credential credentials)
throws NoUserIdException {
Oauth2 userInfoService = new Oauth2.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credentials)
.setApplicationName(APPLICATION_NAME)
.build();
Userinfoplus userInfo = null;
try {
userInfo = userInfoService.userinfo().get().execute();
} catch (IOException e) {
System.err.println("An error occurred: " + e);
}
if (userInfo != null && userInfo.getId() != null) {
return userInfo;
} else {
throw new NoUserIdException();
}
}
/**
* Retrieve the authorization URL.
*
* @param emailAddress User's e-mail address.
* @param state State for the authorization URL.
* @return Authorization URL to redirect the user to.
* @throws IOException Unable to load client_secret.json.
*/
public static String getAuthorizationUrl(String emailAddress, String state)

throws IOException {
GoogleAuthorizationCodeRequestUrl urlBuilder = getFlow()
.newAuthorizationUrl()
.setRedirectUri(REDIRECT_URI)
.setState(state);
urlBuilder.set("user_id", emailAddress);
return urlBuilder.build();
}
/**
* Retrieve credentials using the provided authorization code.
*
* This function exchanges the authorization code for an access token and
* queries the UserInfo API to retrieve the user's e-mail address. If a
* refresh token has been retrieved along with an access token, it is stored
* in the application database using the user's e-mail address as key. If no
* refresh token has been retrieved, the function checks in the application
* database for one and returns it if found or throws a NoRefreshTokenException
* with the authorization URL to redirect the user to.
*
* @param authorizationCode Authorization code to use to retrieve an access
*
token.
* @param state State to set to the authorization URL in case of error.
* @return OAuth 2.0 credentials instance containing an access and refresh
*
token.
* @throws NoRefreshTokenException No refresh token could be retrieved from
*
the available sources.
* @throws IOException Unable to load client_secret.json.
*/
public static Credential getCredentials(String authorizationCode, String state)
throws CodeExchangeException, NoRefreshTokenException, IOException {
String emailAddress = "";
try {
Credential credentials = exchangeCode(authorizationCode);
Userinfoplus userInfo = getUserInfo(credentials);
String userId = userInfo.getId();
emailAddress = userInfo.getEmail();
if (credentials.getRefreshToken() != null) {
storeCredentials(userId, credentials);
return credentials;
} else {
credentials = getStoredCredentials(userId);
if (credentials != null && credentials.getRefreshToken() != null) {
return credentials;
}
}
} catch (CodeExchangeException e) {
e.printStackTrace();

// Drive apps should try to retrieve the user and credentials for the
// current session.
// If none is available, redirect the user to the authorization URL.
e.setAuthorizationUrl(getAuthorizationUrl(emailAddress, state));
throw e;
} catch (NoUserIdException e) {
e.printStackTrace();
}
// No refresh token has been retrieved.
String authorizationUrl = getAuthorizationUrl(emailAddress, state);
throw new NoRefreshTokenException(authorizationUrl);
}
}

Authorizing with stored credentials


When users visit your app after a successful first-time authorization flow, your application can use a stored
refresh token to authorize requests without prompting the end user.
If you have already authenticated the user, your application can retrive the refresh token from its database and
store the token in a server-side session. If the refresh token is revoked or is otherwise invalid, you'll need to
catch this and take appropriate action as described in Handling revoked or invalid refresh tokens.
Using OAuth 2.0 credentials

Once OAuth 2.0 credentials have been retrieved as shown in the previous section, they can be used to authorize
a Drive service object and send requests to the API.
The following code snippets show how to instantiate and authorize a Drive service object and send a request to
the Drive API to retrieve a File's metadata.

Instantiate a service object


This code sample shows how to instantiate a service object and then authorize it to make API requests.
JAVAPYTHONPHP.NET
import
import
import
import

com.google.api.client.auth.oauth2.Credential;
com.google.api.client.http.HttpTransport;
com.google.api.client.http.javanet.NetHttpTransport;
com.google.api.client.json.jackson2.JacksonFactory;

import com.google.api.services.drive.Drive;
// ...
public class MyClass {
private static final String APPLICATION_NAME = "Your app name";
private static final JacksonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
private static final HttpTransport HTTP_TRANSPORT =
new NetHttpTransport();
// ...
/**
* Build a Drive service object.
*
* @param credentials OAuth 2.0 credentials.
* @return Drive service object.
*/
static Drive buildService(Credential credentials) {
return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credentials)
.setApplicationName(APPLICATION_NAME)
.build();
}
// ...
}

Send authorized requests and check for revoked credentials


The following code snippet uses an authorized Drive service instance and sends an authorized GET request to
the Drive API to retrieve a File's metadata.
If an error occurs, the code checks for an HTTP 401 status code, which should be handled by redirecting the
user to the authorization URL.
More Drive API operations are documented in the API Reference.
JAVAPYTHONPHP.NET
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;

import java.io.IOException;
// ...
public class MyClass {
// ...
/**
* Print a file's metadata.
*
* @param service Drive API service instance.
* @param fileId ID of the file to print metadata for.
*/
static void printFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getTitle());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401) {
// Credentials have been revoked.
// TODO: Redirect the user to the authorization URL.
throw new UnsupportedOperationException();
}
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
// ...
}

Next steps

Once you are comfortable authorizing Drive API requests, you're ready to upload files and perform any of the
other operations described in "Manage Drive Files." You can learn more about available API methods in the API
Reference, and you can review our end-to-end Example Apps to examine some working code.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and
code samples are licensed under the Apache 2.0 License. For details, see our Site Policies.
Last updated January 16, 2016.

Blog

Stay up-to-date on developing for Google Apps

Вам также может понравиться