File.setTitle method equivalent in Google Drive API v3 - java

Here is an official example:
package com.google.api.services.samples.drive.cmdline;
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.googleapis.media.MediaHttpDownloader;
import com.google.api.client.googleapis.media.MediaHttpUploader;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
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.util.Preconditions;
import com.google.api.client.util.store.DataStoreFactory;
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 java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Collections;
/**
* A sample application that runs multiple requests against the Drive API. The requests this sample
* makes are:
* <ul>
* <li>Does a resumable media upload</li>
* <li>Updates the uploaded file by renaming it</li>
* <li>Does a resumable media download</li>
* <li>Does a direct media upload</li>
* <li>Does a direct media download</li>
* </ul>
*
* #author rmistry#google.com (Ravi Mistry)
*/
public class DriveSample {
/**
* Be sure to specify the name of your application. If the application name is {#code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = "";
private static final String UPLOAD_FILE_PATH = "Enter File Path";
private static final String DIR_FOR_DOWNLOADS = "Enter Download Directory";
private static final java.io.File UPLOAD_FILE = new java.io.File(UPLOAD_FILE_PATH);
/** Directory to store user credentials. */
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/drive_sample");
/**
* Global instance of the {#link DataStoreFactory}. The best practice is to make it a single
* globally shared instance across your application.
*/
private static FileDataStoreFactory dataStoreFactory;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global Drive API client. */
private static Drive drive;
/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(DriveSample.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=drive "
+ "into drive-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(DriveScopes.DRIVE_FILE)).setDataStoreFactory(dataStoreFactory)
.build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) {
Preconditions.checkArgument(
!UPLOAD_FILE_PATH.startsWith("Enter ") && !DIR_FOR_DOWNLOADS.startsWith("Enter "),
"Please enter the upload file path and download directory in %s", DriveSample.class);
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
// authorization
Credential credential = authorize();
// set up the global Drive instance
drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
// run commands
View.header1("Starting Resumable Media Upload");
File uploadedFile = uploadFile(false);
View.header1("Updating Uploaded File Name");
File updatedFile = updateFileWithTestSuffix(uploadedFile.getId());
View.header1("Starting Resumable Media Download");
downloadFile(false, updatedFile);
View.header1("Starting Simple Media Upload");
uploadedFile = uploadFile(true);
View.header1("Starting Simple Media Download");
downloadFile(true, uploadedFile);
View.header1("Success!");
return;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
/** Uploads a file using either resumable or direct media upload. */
private static File uploadFile(boolean useDirectUpload) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Insert insert = drive.files().insert(fileMetadata, mediaContent);
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
/** Updates the name of the uploaded file to have a "drivetest-" prefix. */
private static File updateFileWithTestSuffix(String id) throws IOException {
File fileMetadata = new File();
fileMetadata.setTitle("drivetest-" + UPLOAD_FILE.getName());
Drive.Files.Update update = drive.files().update(id, fileMetadata);
return update.execute();
}
/** Downloads a file using either resumable or direct media download. */
private static void downloadFile(boolean useDirectDownload, File uploadedFile)
throws IOException {
// create parent directory (if necessary)
java.io.File parentDir = new java.io.File(DIR_FOR_DOWNLOADS);
if (!parentDir.exists() && !parentDir.mkdirs()) {
throw new IOException("Unable to create parent directory");
}
OutputStream out = new FileOutputStream(new java.io.File(parentDir, uploadedFile.getTitle()));
MediaHttpDownloader downloader =
new MediaHttpDownloader(httpTransport, drive.getRequestFactory().getInitializer());
downloader.setDirectDownloadEnabled(useDirectDownload);
downloader.setProgressListener(new FileDownloadProgressListener());
downloader.download(new GenericUrl(uploadedFile.getDownloadUrl()), out);
}
}
One problem is that the setTitle method does not exist any more in the latest Java API. How do I set the title of a file now?

Some changes in above code
setTitle has been changed into setName
Drive.Files.Insert -> Drive.Files.Create
drive.files().insert(fileMetadata, mediaContent); -> drive.files().create(fileMetadata, mediaContent)
getTitle() -> getName()
uploadedFile.getDownloadUrl() -> uploadedFile.getWebViewLink()
Following code has all new Method names.
change last part of code and paste
private static File uploadFile(boolean useDirectUpload) throws IOException {
File fileMetadata = new File();
fileMetadata.setName(UPLOAD_FILE.getName());
FileContent mediaContent = new FileContent("image/jpeg", UPLOAD_FILE);
Drive.Files.Create insert = drive.files().create(fileMetadata, mediaContent);
MediaHttpUploader uploader = insert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(useDirectUpload);
uploader.setProgressListener(new FileUploadProgressListener());
return insert.execute();
}
/** Updates the name of the uploaded file to have a "drivetest-" prefix. */
private static File updateFileWithTestSuffix(String id) throws IOException {
File fileMetadata = new File();
fileMetadata.setName("drivetest-" + UPLOAD_FILE.getName());
Drive.Files.Update update = drive.files().update(id, fileMetadata);
return update.execute();
}
/** Downloads a file using either resumable or direct media download. */
private static void downloadFile(boolean useDirectDownload, File uploadedFile)
throws IOException {
// create parent directory (if necessary)
java.io.File parentDir = new java.io.File(DIR_FOR_DOWNLOADS);
if (!parentDir.exists() && !parentDir.mkdirs()) {
throw new IOException("Unable to create parent directory");
}
OutputStream out = new FileOutputStream(new java.io.File(parentDir, uploadedFile.getName()));
MediaHttpDownloader downloader =
new MediaHttpDownloader(httpTransport, drive.getRequestFactory().getInitializer());
downloader.setDirectDownloadEnabled(useDirectDownload);
downloader.setProgressListener(new FileDownloadProgressListener());
downloader.download(new GenericUrl(uploadedFile.getWebViewLink()), out);
}

setTitle has been changed into setName in v3.

Related

java.lang.NoSuchMethodError: com.google.api.client.http.javanet.NetHttpTransport.<init>(Lcom/google/api/client/http/javanet/ConnectionFactory;

Good morning. My program wants to communicate with my google drive account. So I took example to see how I can do it. But I have the same error still now. Please help me.
The problem is on this line :
NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
When I'm execute I have this error:
com.google.api.client.http.javanet.NetHttpTransport.(Lcom/google/api/client/http/javanet/ConnectionFactory;Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/HostnameVerifier;)
My source 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.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.FileInputStream;
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 {
static final String oz = org.apache.http.conn.ssl .SSLConnectionSocketFactory.class.getProtectionDomain (). getCodeSource(). getLocation (). getPath ();
private static final String APPLICATION_NAME = "DriveQuickstart";
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
// Directory to store user credentials for this application.
private static final java.io.File CREDENTIALS_FOLDER //
= new java.io.File(System.getProperty("user.home"), "credentials");
private static final String CLIENT_SECRET_FILE_NAME = "client_secret.json";
//
// Global instance of the scopes required by this quickstart. If modifying these
// scopes, delete your previously saved credentials/ folder.
//
private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE);
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
java.io.File clientSecretFilePath = new java.io.File(CREDENTIALS_FOLDER, CLIENT_SECRET_FILE_NAME);
if (!clientSecretFilePath.exists()) {
throw new FileNotFoundException("Please copy " + CLIENT_SECRET_FILE_NAME //
+ " to folder: " + CREDENTIALS_FOLDER.getAbsolutePath());
}
// Load client secrets.
InputStream in = new FileInputStream(clientSecretFilePath);
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(CREDENTIALS_FOLDER))
.setAccessType("offline").build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String... args) throws IOException, GeneralSecurityException {
System.out.println("voici le path "+oz);
System.out.println("CREDENTIALS_FOLDER: " + CREDENTIALS_FOLDER.getAbsolutePath());
// 1: Create CREDENTIALS_FOLDER
if (!CREDENTIALS_FOLDER.exists()) {
CREDENTIALS_FOLDER.mkdirs();
System.out.println("Created Folder: " + CREDENTIALS_FOLDER.getAbsolutePath());
System.out.println("Copy file " + CLIENT_SECRET_FILE_NAME + " into folder above.. and rerun this class!!");
return;
}
// 2: Build a new authorized API client service.
NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
// 3: Read client_secret.json file & create Credential object.
Credential credential = getCredentials(HTTP_TRANSPORT);
// 5: Create Google Drive Service.
Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) //
.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());
}
}
}
}
This is a jar dependency issue. Update your question with a screenshot of libs folder.
In order to work this please add the below jars in lib if not exists already
google-oauth-client-1.30.5.jar
google-oauth-client-java6-1.30.6.jar
google-oauth-client-jetty-1.30.6.jar
google-api-client-1.30.9.jar
google-http-client-1.34.0.jar
google-http-client-jackson2-1.34.2.jar
google-api-services-drive-v3-rev195-1.25.0.jar
httpclient-4.5.12.jar
Also, add the below lines of code just above where the exception is occurring to see from which jar they are referenced in
System.out.println(NetHttpTransport.class.getProtectionDomain().getCodeSource().getLocation().getPath());
System.out.println(GoogleNetHttpTransport.class.getProtectionDomain().getCodeSource().getLocation().getPath());
NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
use your class package while calling the class
HttpTransport httpTransport = new com.google.api.client.http.javanet.NetHttpTransport();
I hope it will work

Working java code to read the demo Google Sheet in a project?

Having tried working with code snippets from various sources and posts, can anyone actually post a complete (with imports) starting-point working java example that can be used within a project, to connect to a demo Google sheet and (at least) read data? This would be good for those looking for a basic working mechanism to play with and tailor further.
For example, based on the Google sample at:
https://developers.google.com/sheets/api/quickstart/java
which aims to get data from the demo Sheet noted in the code:
https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
Jars obtained from:
https://developers.google.com/resources/api-libraries/download/sheets/v4/java
A 'client_secret.json' file will also need to be generated, as per Google's instructions, and made available to the project.
What looks like the most comprehensive sample so far, I've found on GitHub. (code below) Thanks to Google & jovito-royeca/Hourlify. (It also looks to be able to add data to a sheet, but probably a different bridge to cross)
For me, with the jars and client_secret.json present, when running the code I am returned:
May 09, 2017 4:36:10 PM com.google.api.client.util.store.FileDataStoreFactory setPermissionsToOwnerOnly
WARNING: unable to change permissions for everybody: C:\Users\David\.credentials\sheets.googleapis.com-java-quickstart.json
May 09, 2017 4:36:10 PM com.google.api.client.util.store.FileDataStoreFactory setPermissionsToOwnerOnly
WARNING: unable to change permissions for owner: C:\Users\David\.credentials\sheets.googleapis.com-java-quickstart.json
Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at teamExample.SheetsQuickstart.authorize(SheetsQuickstart.java:70)
at teamExample.SheetsQuickstart.getSheetsService(SheetsQuickstart.java:93)
at teamExample.SheetsQuickstart.readSampleSpreadsheet(SheetsQuickstart.java:113)
at teamExample.SheetsQuickstart.main(SheetsQuickstart.java:105)
Full code, adapted slightly from the GitHub repo:
/*
* Sample java to access, read and write data in Google Sheets.
*/
package teamExample;
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.HttpTransport;
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.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.*;
import com.google.api.services.sheets.v4.Sheets;
import java.io.*;
import java.util.*;
public class SheetsQuickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"Google Sheets API 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/sheets.googleapis.com-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/sheets.googleapis.com-java-quickstart.json
*/
private static final List<String> SCOPES =
Arrays.asList(SheetsScopes.SPREADSHEETS);
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 {
// Load client secrets.
InputStream in =
SheetsQuickstartA.class.getResourceAsStream("/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("force")
.build();
Credential credential = new AuthorizationCodeInstalledApp(
flow, new LocalServerReceiver()).authorize("user");
System.out.println(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized Sheets API client service.
* #return an authorized Sheets API client service
* #throws IOException
*/
public static Sheets getSheetsService() throws IOException {
Credential credential = authorize();
return new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String[] args) throws Exception {
//createHourlifyEmployees();
readSampleSpreadsheet();
}
public static void readSampleSpreadsheet() throws IOException {
// Build a new authorized API client service.
Sheets service = getSheetsService();
// Prints the names and majors of students in a sample spreadsheet:
// https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
String spreadsheetId = "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms";
String range = "Class Data!A2:E";
ValueRange response = service.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values == null || values.size() == 0) {
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));
}
}
}
public static void createHourlifyEmployees() throws Exception {
String spreadsheetId = "14oUVpOkT_mcwOIvOn643g7Q_OktdCkdru4NpURMlUhU";
int employeeCount = 200;
ArrayList<ValueRange> values = new ArrayList<>();
List lastNames = arrayFromFile("lastname.csv");
List firstNames = arrayFromFile("firstname.csv");
for (int i=0; i<employeeCount; i++) {
Random rand1 = new Random();
Random rand2 = new Random();
ValueRange value = new ValueRange();
ArrayList<Object> arrayList = new ArrayList();
ArrayList<Object> row = new ArrayList();
row.add(i+1000);
row.add(lastNames.get(rand1.nextInt(lastNames.size()-1)));
row.add(firstNames.get(rand2.nextInt(firstNames.size()-1)));
arrayList.add(row);
value.set("values", arrayList);
value.setRange("Employees!A"+(i+2)+":C"+(i+2));
values.add(value);
}
BatchUpdateValuesRequest request = new BatchUpdateValuesRequest();
request.setValueInputOption("RAW");
request.setData(values);
Sheets service = getSheetsService();
service.spreadsheets().values().batchUpdate(spreadsheetId, request).execute();
}
public static List<Map<String,String>> generateNames() {
// List lastNames = arrayFromFile("lastname.csv");
// List firstNames = arrayFromFile("firstname.csv");
ArrayList<Map<String,String>> array = new ArrayList();
int number = 150;
for (int i=0; i<number; i++) {
}
return array;
}
public static List<String> arrayFromFile(String fileName) throws Exception {
ArrayList<String> array = new ArrayList();
InputStream in = SheetsQuickstartA.class.getClassLoader().getResourceAsStream(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
array.add(line);
}
return array;
}
}
Many thanks. Hopefully this will be useful to others.

Google Drive API Java, Authentication works for first time only

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.

Google Drive API REST V2 insert file into folder file not found

I am trying to upload a file into one of my company's Google Drive folders but I haven't managed to achieve this without client intervention. So, whenever I use this:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
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.jackson2.JacksonFactory;
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.ParentReference;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class DriveCommandLine_srive
{
private static String CLIENT_ID = "myClientID.apps.googleusercontent.com";
private static String CLIENT_SECRET = "myClientSecret";
private static String REDIRECT_URI = "mything";
public static void main( String[] args ) throws IOException
{
HttpTransport httpTransport = new NetHttpTransport( );
JsonFactory jsonFactory = new JacksonFactory( );
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, Arrays.asList( DriveScopes.DRIVE ) ).setAccessType( "online" ).setApprovalPrompt( "auto" ).build( );
System.out.println("xxxxx : " + DriveScopes.DRIVE);
String url = flow.newAuthorizationUrl( ).setRedirectUri( REDIRECT_URI ).build( );
System.out.println( "Please open the following URL in your browser then type the authorization code:" );
System.out.println( " " + url );
BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
String code = br.readLine( );
GoogleTokenResponse response = flow.newTokenRequest( code ).setRedirectUri( REDIRECT_URI ).execute( );
GoogleCredential credential = new GoogleCredential( ).setFromTokenResponse( response );
// Create a new authorized API client
Drive service = new Drive.Builder( httpTransport, jsonFactory, credential ).build( );
insertFile(service, "Test File Drive", "This is a test file","myCompanysFolderID" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
}
I manage to successfully upload the file to the company's folder, but I have to authorize it manually and paste the code each time. So, as I want to make this in an automatic way, I changed the authorization "method" to one that uses a service account p12 key to authorize the client. This is the new code after the change:
package sample;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
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.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.ParentReference;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class DriveCommandLine2
{
private static final String KEY_FILE_LOCATION = "data/myp12Key.p12";
**//Note: this is the mail from a service account in my dev console, it is different from the OAuth client I use in the previous method.**
private static final String SERVICE_ACCOUNT_EMAIL ="myServiceAccountEmail#appspot.gserviceaccount.com";
/** Application name. */
private static final String APPLICATION_NAME =
"Drive API Java Quickstart";
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY =
JacksonFactory.getDefaultInstance();
public static void main( String[] args ) throws Exception
{
//Drive service = getServiceManual();
Drive service = initializeDrive();
//insertFile(service, "Test File Drive", "This is a test file","myCompanyFolderID" , "text/plain", "./data/document.txt");
insertFile(service, "Test File Drive", "This is a test file","" , "text/plain", "./data/document.txt");
}
/**
* Insert new file.
*
* #param service Drive API service instance.
* #param title Title of the file to insert, including the extension.
* #param description Description of the file to insert.
* #param parentId Optional parent folder's ID.
* #param mimeType MIME type of the file to insert.
* #param filename Filename of the file to insert.
* #return Inserted file metadata if successful, {#code null} otherwise.
*/
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
/////////////////////
///NEW GOOGLE ANALYTICS AUTH
public static java.io.File convIs2File(InputStream inputStream, java.io.File file)
{
java.io.OutputStream outputStream = null;
try {
// write the inputStream to a FileOutputStream
outputStream = new java.io.FileOutputStream(file);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
// outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
private static Drive initializeDrive() throws Exception {
// Initializes an authorized analytics service object.
// Construct a GoogleCredential object with the service account email
// and p12 file downloaded from the developer console.
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
InputStream is = DriveCommandLine2.class.getClassLoader().getResourceAsStream(KEY_FILE_LOCATION);
java.io.File f = java.io.File.createTempFile("myP12Key", ".p12");
java.io.File f_used = convIs2File(is,f);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(f_used)
.setServiceAccountScopes(DriveScopes.all())
.build();
// Construct the Analytics service object.
return new Drive.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
}
}
But when I run this code, I get the following error:
An error occured: com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
"code" : 404,
"errors" : [ {
"domain" : "global",
"location" : "file",
"locationType" : "other",
"message" : "File not found: myCompanyFolderID",
"reason" : "notFound"
} ],
"message" : "File not found: myCompanyFolderID"
}
So, my guess is that in the previous authorization way, I am using my Client_ID and Client_Secrets to authorize my app to insert things into my company's Drive space, so I find myCompanyFolder and I am able to insert the file successfully, however, in the second method, I am trying to insert the file into the service account Drive space that I am not able to access (I know this because when I try to insert it in Drive's root, it works perfectly, however, I am not able to see the file in my root).
So at the end, my question is, is there a way to insert the file into my company's drive folder without doing the manual authorization? That is, how do I authorize my app to upload the file in my company's drive without human interaction?
I think the client_secrets way won't work as I tried it before and it asks me to do it manually the first time I run the code. As I am running my code from a JAR file in a Linux server, this is not practical at all and doesn't work for me.
Thanks!
The 404: File not found means that the user does not have read access to a file or the file does not exist.
Make sure that you provide the correct access_token when making the request for file metadata. Try to regenerate the authorization code, access_token. You need to authorize and authenticate your requests on the behalf of the user, a key and your client ID will not be enough to access user's document.
The documentation suggest to report to users that they do not have read access to the file or that the file does not exist. Tell them that they should ask the owner for permission to the file.

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