Google Drive API Java, Authentication works for first time only - java

I use following code to upload file to google drive, it is used for java based web application. Everything works fine except authentication.
The main problem with the code is that it just ask once for authentication and later on when I run the project, it never ask for authentication.
I want authentication for each and every request made by client.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package myapp.util;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.*;
import com.google.api.services.drive.Drive;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
public class GDrive {
/**
* Application name.
*/
private static final String APPLICATION_NAME
= "Drive API Java Quickstart";
/**
* Directory to store user credentials for this application.
*/
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/drive-java-quickstart.json");
/**
* Global instance of the {#link FileDataStoreFactory}.
*/
private static FileDataStoreFactory DATA_STORE_FACTORY;
/**
* Global instance of the JSON factory.
*/
private static final JsonFactory JSON_FACTORY
= JacksonFactory.getDefaultInstance();
/**
* Global instance of the HTTP transport.
*/
private static HttpTransport HTTP_TRANSPORT;
/**
* Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials at
* ~/.credentials/drive-java-quickstart
*/
private static final List<String> SCOPES
= Arrays.asList(DriveScopes.DRIVE_FILE);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
*
* #return an authorized Credential object.
* #throws IOException
*/
public static Credential authorize() throws IOException {
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
String basePath = servletContext.getRealPath("");
basePath = URLDecoder.decode(basePath, "UTF-8");
// Load client secrets.
InputStream in = new FileInputStream(
new java.io.File(basePath + "/resources/client_secret.json"));
GoogleClientSecrets clientSecrets
= GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow
= new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.setApprovalPrompt("auto")
.build();
GoogleCredential credential = new GoogleCredential();
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized Drive client service.
*
* #return an authorized Drive client service
* #throws IOException
*/
public static Drive getDriveService() throws IOException {
Credential credential = authorize();
System.out.println("getAccessToken" + credential.getAccessToken());
System.out.println("setAccessToken" + credential.getAccessToken());
System.out.println("setExpiresInSeconds" + credential.getExpiresInSeconds());
System.out.println("setRefreshToken" + credential.getRefreshToken());
return new Drive.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public boolean uploadToDrive(String filePathUrl, String fileName) throws FileNotFoundException, IOException, GeneralSecurityException, Exception {
Drive service = GDrive.getDriveService();
boolean status = false;
// TODO code application logic here
java.io.File mediaFile = new java.io.File(filePathUrl);
com.google.api.services.drive.model.File fileMetadata = new com.google.api.services.drive.model.File();
fileMetadata.setName(fileName);
InputStreamContent mediaContent = new InputStreamContent("application/octet-stream", new BufferedInputStream(new FileInputStream(mediaFile)));
mediaContent.setLength(mediaFile.length());
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive.Files.Create request = service.files().create(fileMetadata, mediaContent);
request.getMediaHttpUploader().setProgressListener(new CustomProgressListener());
request.execute();
status = true;
return status;
}
}
class CustomProgressListener implements MediaHttpUploaderProgressListener {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
System.out.println("Initiation has started!");
break;
case INITIATION_COMPLETE:
System.out.println("Initiation is complete!");
break;
case MEDIA_IN_PROGRESS:
System.out.println(uploader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Upload is complete!");
}
}
}

By design the client library stores authorization information, so that the user isn't prompted every time they run your application. The client library persists authorization information to the DataStore instance you provide, in your case a FileDataStore which stores files in a particular directory.
Multiple users can share the same data store, but you need to pass a unique user identifier when performing authorization. For installed applications this is done in AuthorizationCodeInstalledApp.authorize, and for web applications it's done by overriding AbstractAuthorizationCodeServlet.getUserId and AbstractAuthorizationCodeCallbackServlet.getUserId. See the Java client library's OAuth2 guide for more information and examples.

Related

Authenticate with a Service Account for Google Sheets API with Java

I started with the Google Quick Start guide for Java for connecting to Google Sheets via their API (https://developers.google.com/sheets/api/quickstart/java). I am following their quick start tutorial as it is without any changes. However, instead of creating an OAuth client ID and downloading that JSON credentials file, I created a Service Account (because that's what it's going to be). However, the downloaded service account JSON file does not work with Google's Quick Start code :
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
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.util.store.FileDataStoreFactory;
import com.google.api.services.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.ValueRange;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
public class SheetsQuickstart {
private static final String APPLICATION_NAME = "Google Sheets API Java Quickstart";
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(SheetsScopes.SPREADSHEETS_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = SheetsQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
/**
* Prints the names and majors of students in a sample spreadsheet:
* https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
*/
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
final String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
final String range = "Class Data!A2:E";
Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
ValueRange response = service.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values == null || values.isEmpty()) {
System.out.println("No data found.");
} else {
System.out.println("Name, Major");
for (List row : values) {
// Print columns A and E, which correspond to indices 0 and 4.
System.out.printf("%s, %s\n", row.get(0), row.get(4));
}
}
}
}
and it gives this exception:
Task :run FAILED
Exception in thread "main" java.lang.IllegalArgumentException
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:131)
at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:35)
at com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.getDetails(GoogleClientSecrets.java:80)
at com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder.(GoogleAuthorizationCodeFlow.java:211)
at SheetsQuickstart.getCredentials(SheetsQuickstart.java:50)
at SheetsQuickstart.main(SheetsQuickstart.java:68)
I have already given 'Edit' access to the service account email id given in the json file to my Google spreadsheet, but it still gives the same error (in fact I tried changing my file permissions to 'anyone with link' can edit, and have used the same google spreadsheet ID in the code). Some webpages suggested a deprecated GoogleCredential based solution. Is there a non-deprecated solution to the problem?

Exception in thread "main" java.lang.NoClassDefFoundError: org/mortbay/jetty/Handler

I am trying to run the tutorial google drive api test
package Tests;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
public class DriveQuickstart {
private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
private static final String CREDENTIALS_FILE_PATH = "credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// Print the names and IDs for up to 10 files.
FileList result = service.files().list()
.setPageSize(10)
.setFields("nextPageToken, files(id, name)")
.execute();
List<File> files = result.getFiles();
if (files == null || files.isEmpty()) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
}
}
I have almost all jars mentioned and I have downloaded the config.json file. However I get the following error
WARNING: unable to change permissions for owner: C:\Users\aswat\git\bionovaQAnew\tokens
Exception in thread "main" java.lang.NoClassDefFoundError: org/mortbay/jetty/Handler
at com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver$Builder.build(LocalServerReceiver.java:205)
at Tests.DriveQuickstart.getCredentials(DriveQuickstart.java:57)
at Tests.DriveQuickstart.main(DriveQuickstart.java:64)
Caused by: java.lang.ClassNotFoundException: org.mortbay.jetty.Handler
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 3 more
I have tried out multiple answers mentioned in stackoverflow.com/questions/50687434/error-running-spark-main-class-exception-in-thread-thread-0-java-lang-noclas, but it doesnt help me. I have attached my buildpath dependencies as well. Please let me know what the issue is.
I use Ant and eclipse.
After many trials what worked for me was:
Added guava-11.0.2.jar
Removed google api client json 1 2 3 alpha.jar
Re downloaded the credential.json
Started a new project with just the required jars in resource file as shown attached

Nullpointer when getResourceAsStream(credentials.json) in Android Studio

According to Google Calendar API Quickstart for java (step 3), we can use
InputStream in = CalendarQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
to parse credentials.json.
However, it only works when running the file outside of Android Studio. Running the CalendarQuickStart.java main method (without running the app) in Android Studio will result nullpointer exception.
I found that using getAsset()is probably a way to get around the problem
InputStream in = context.getAssets().open(CREDENTIALS_FILE_PATH);.
Its' easy to set up asset folders but getting context to work is very tricky.
Here is my file path:
Here is my code:
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
public class CalendarQuickstart extends AppCompatActivity {
private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES = Collections.singletonList(CalendarScopes.CALENDAR_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = CalendarQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
//InputStream in = context.getAssets().open(CREDENTIALS_FILE_PATH);
System.out.println(in);
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
// List the next 20 events from the primary calendar.
DateTime now = new DateTime(System.currentTimeMillis());
Events events = service.events().list("primary")
.setMaxResults(20)
.setTimeMin(now)
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();
List<Event> items = events.getItems();
if (items.isEmpty()) {
System.out.println("No upcoming events found.");
} else {
System.out.println("Upcoming events");
for (Event event : items) {
DateTime start = event.getStart().getDateTime();
if (start == null) {
start = event.getStart().getDate();
}
System.out.printf("%s (%s)\n", event.getSummary(), start);
}
}
}
}
What is a better way to run the CalendarQuickstart.java in Android Studio?

Google Subscription Defer using Java Client Libraries give 500 Internal Server Error

package com.google.play.developerapi.samples;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import javax.annotation.Nullable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.repackaged.com.google.common.base.Preconditions;
import com.google.api.client.repackaged.com.google.common.base.Strings;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisher.Purchases;
import com.google.api.services.androidpublisher.AndroidPublisher.Purchases.Subscriptions;
import com.google.api.services.androidpublisher.AndroidPublisher.Purchases.Subscriptions.Defer;
import com.google.api.services.androidpublisher.AndroidPublisher.Purchases.Subscriptions.Get;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import com.google.api.services.androidpublisher.model.SubscriptionDeferralInfo;
import com.google.api.services.androidpublisher.model.SubscriptionPurchase;
import com.google.api.services.androidpublisher.model.SubscriptionPurchasesDeferRequest;
public class AndroidPublisherHelper {
private static final Log log = LogFactory.getLog(AndroidPublisherHelper.class);
static final String MIME_TYPE_APK = "application/vnd.android.package-archive";
/** Path to the private key file (only used for Service Account auth). */
private static final String SRC_RESOURCES_KEY_P12 = "resources/key.p12";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
private static Credential authorizeWithServiceAccount(String serviceAccountEmail)
throws GeneralSecurityException, IOException {
log.info(String.format("Authorizing using Service Account: %s", serviceAccountEmail));
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(serviceAccountEmail)
.setServiceAccountScopes(
Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
.setServiceAccountPrivateKeyFromP12File(new File(SRC_RESOURCES_KEY_P12))
.build();
return credential;
}
/**
* Performs all necessary setup steps for running requests against the API
* using the Installed Application auth method.
*
* #param applicationName the name of the application: com.example.app
* #return the {#Link AndroidPublisher} service
*/
protected static AndroidPublisher init(String applicationName) throws Exception {
return init(applicationName, "abcdefghijk#developer.gserviceaccount.com");
}
/**
* Performs all necessary setup steps for running requests against the API.
*
* #param applicationName the name of the application: com.example.app
* #param serviceAccountEmail the Service Account Email (empty if using
* installed application)
* #return the {#Link AndroidPublisher} service
* #throws GeneralSecurityException
* #throws IOException
*/
protected static AndroidPublisher init(String applicationName,
#Nullable String serviceAccountEmail) throws IOException, GeneralSecurityException {
Preconditions.checkArgument(!Strings.isNullOrEmpty(applicationName),
"applicationName cannot be null or empty!");
// Authorization.
newTrustedTransport();
Credential credential;
credential = authorizeWithServiceAccount(serviceAccountEmail);
// Set up and return API client.
return new AndroidPublisher.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(applicationName)
.build();
}
private static void newTrustedTransport() throws GeneralSecurityException,
IOException {
if (null == HTTP_TRANSPORT) {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
}
}
public static void main(String args[])
{
try {
AndroidPublisher publisher=init("App payment");
System.out.println(publisher);
Purchases purchases = publisher.purchases();
Subscriptions subscriptions=purchases.subscriptions();
Get get = subscriptions.get("package", "productId", "purchaseToken");
SubscriptionPurchase subscripcion = get.execute(); //Exception returned here
System.out.println(subscripcion);
SubscriptionDeferralInfo deferralInfo =new SubscriptionDeferralInfo();
deferralInfo.setExpectedExpiryTimeMillis(subscripcion.getExpiryTimeMillis());
deferralInfo.setDesiredExpiryTimeMillis(1430837304000l);
SubscriptionPurchasesDeferRequest request= new SubscriptionPurchasesDeferRequest();
request.setDeferralInfo(deferralInfo);
Defer defer=subscriptions.defer("package", "productId", "purchaseToken", request);
System.out.println(defer.executeUnparsed().toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
get.execute() work and it give details like token, purchase time and other details but defer gives
com.google.api.client.googleapis.json.GoogleJsonResponseException: 500 Internal Server Error
{
"code" : 500,
"message" : null
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1049)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
It was giving problem in test account, but it got solved when I switched to Live account.

Display the list of files using Google Drive SDK API in Java

I can not fix...below you can find the code:
import java.io.IOException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
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.jackson.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class getDriveService {
/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL = "<email_address_service>#developer.gserviceaccount.com";
/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "src/<file_key>-privatekey.p12";
public static void main(String[] args) throws IOException, GeneralSecurityException, URISyntaxException {
List<File> lista = null;
lista = retrieveAllFiles(getDriveService());
System.out.println(""+lista.size());
for (File file : lista) {
System.out.println(""+file.getId());
}
}
/**
* Build and returns a Drive service object authorized with the service accounts
* that act on behalf of the given user.
*
* #param userEmail The email of the user.
* #return Drive service object that is ready to make requests.
*/
public static Drive getDriveService() throws GeneralSecurityException,
IOException, URISyntaxException {
Collection<String> elenco = new ArrayList<String>();
elenco.add("https://www.googleapis.com/auth/drive");
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(elenco)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
.setApplicationName("FileListAccessProject")
.setHttpRequestInitializer(credential).build();
return service;
}
/**
* Retrieve a list of File resources.
*
* #param service Drive API service instance.
* #return List of File resources.
*/
private static List<File> retrieveAllFiles(Drive service) throws IOException {
List<File> result = new ArrayList<File>();
Files.List request = service.files().list();
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
System.out.println("An error occurred: " + e);
request.setPageToken(null);
}
} while (request.getPageToken() != null &&
request.getPageToken().length() > 0);
return result;
}
}
If I run the main method, it display "0". The file list is empty. Why?
The code seem right, I also enabled the service "Drive API" from the Google APIs Console panel ... and I left disabled "Drive SDK" (which I do not understand why, but here https://developers.google.com/drive/delegation says so)
What could be wrong? Did I forget something?
Thanks in advance for any help
Francesco
You must set ServiceAccountUser as the user's drive you wanna access, and ServiceAccountId as the Service Account User
something like this:
GoogleCredential credentialUser = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountUser("user#gmail.com")
.setServiceAccountPrivateKeyFromP12File(new File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.setServiceAccountScopes(serviceAccountScopes).build();

Categories