I'm using a pretty simple sample to retrieve my files on google drive. There are 2 weird things
The first time when I run the sample, google says "the application would like to access your files blahblah". Well, I confirmed. But, the second time, it says "the application would like to Have offline access"... ah... why?
Probably(but I'm not sure), it's after I confirm it the 2nd time, I only get the files that I uploaded by this application
The code is
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.GoogleUtils;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
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.http.javanet.NetHttpTransport;
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 com.google.api.services.drive.model.FileList;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Collections;
import java.util.List;
/**
* 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 = "testing";
private static final String UPLOAD_FILE_PATH = "c:\\Users\\bnie\\workspace\\Servers\\.project";
private static final String DIR_FOR_DOWNLOADS = "c:\\temp";
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();
NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
builder.trustCertificates(GoogleUtils.getCertificateTrustStore());
httpTransport = builder.build();
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();
FileList l = drive.files().list().setMaxResults(10).execute();
List<File> files = l.getItems();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getTitle(), file.getId());
}
}
// 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);
}
}
Try to change the scope that you used. Used the scope DriveScopes.DRIVE instead of DriveScopes.DRIVE_FILE. For more information about scopes, check this documentation.
Also check this related SO question.
Related
I am writing a java application that interacts with the google sheets api. I have a method that returns the object for a given cell, and then writes a blank string to that cell. The part I am missing is that I want to write to the cell only if its current contents have strikethrough formatting. If I understand the documentation, the object I have returned should contain a textFormat object that contains a boolean value for strikethrough. I have no idea how I can access that value for my condition, however. Can someone advise please?
Note: I am a beginner.
public static void deleteStrikethroughValue (String spreadsheetId, int sheetId, String text, int column, int row, String inputTableRange) throws GeneralSecurityException, IOException {
//returns cell object
List<List<Object>> tableContents = SheetsQuickstart.getValues(inputTableRange);
int sheet2RowNumber = 0;
Object cellValue = "";
for (List row2 : tableContents) {
sheet2RowNumber = sheet2RowNumber+1;
if (sheet2RowNumber == row) {
cellValue = row2.get(column);
}
}
//writes to cell
if (XXXXXX) {
Sheets service = SheetsQuickstart.getSheetsService();
List<Request> requests = new ArrayList<Request>();
List<CellData> values = new ArrayList<CellData>();
values.add(new CellData()
.setUserEnteredValue(new ExtendedValue()
.setStringValue("")));
requests.add(new Request()
.setUpdateCells(new UpdateCellsRequest()
.setStart(new GridCoordinate()
.setSheetId(sheetId)
.setRowIndex(row)
.setColumnIndex(column))
.setRows(Arrays.asList(
new RowData().setValues(values)))
.setFields("userEnteredValue,userEnteredFormat.backgroundColor")));
BatchUpdateSpreadsheetRequest batchUpdateRequest = new BatchUpdateSpreadsheetRequest()
.setRequests(requests);
service.spreadsheets().batchUpdate(spreadsheetId, batchUpdateRequest)
.execute();
}
else {
System.out.println("did not match");
}
}
In order to get the strikethrough value you should use Sheets API Method: spreadsheets.get
By using the Quickstart example I made the following changes to get the strikethrough value from a cell:
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.auth.oauth2.GoogleCredential;
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.sheets.v4.Sheets;
import com.google.api.services.sheets.v4.SheetsScopes;
import com.google.api.services.sheets.v4.model.Spreadsheet;
import com.google.api.services.sheets.v4.model.Sheet;
import com.google.api.services.sheets.v4.model.GridData;
import com.google.api.services.sheets.v4.model.RowData;
import com.google.api.services.sheets.v4.model.CellData;
import com.google.api.services.sheets.v4.model.CellFormat;
import com.google.api.services.sheets.v4.model.TextFormat;
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.ArrayList;
import java.util.List;
public class Main {
private static final String APPLICATION_NAME = "Google Sheets 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(SheetsScopes.SPREADSHEETS);
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 = Main.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).setCallbackPath("/").build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
/**
* Google sheets api (java) - how to access cell's strikethrough value
*
*/
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Sheets service = new Sheets.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
/* HERE STARTS YOUR CODE */
String spreadsheetId = "ID";
List<String> ranges = new ArrayList<>();
ranges.add("A1:B2");
Spreadsheet spreadsheet = service.spreadsheets()
.get(spreadsheetId)
.setRanges(ranges)
.setIncludeGridData(true)
.execute();
// 0 represents the first Sheet in your spreadsheet
int sheetIndex = 0;
Sheet sheet = spreadsheet.getSheets().get(sheetIndex);
GridData gridData = sheet.getData().get(0);
// 1 represents the row 2 in your sheet
int row = 1;
RowData rowData = gridData.getRowData().get(row);
// 1 represents the column B
int column = 1;
CellData cellData = rowData.getValues().get(column);
// This will print the First sheet on my
// spreadsheet cell B2 strikethrough value
System.out.println(
cellData
.getEffectiveFormat()
.getTextFormat()
.getStrikethrough()
);
/* HERE ENDS YOUR CODE */
}
}
Where cellData.getEffectiveFormat().getTextFormat().getStrikethrough() on line 102 will print the boolean value (strikethrough).
Sheets API References
Method: spreadsheets.get
Resource: Spreadsheet
Resource: Sheet
Resource: GridData
Resource: RowData
Resource: CellData
Resource: CellFormat
Resource: TextFormat
Google Sheets Java library references
Class Sheets.Spreadsheets
Class Sheets.Spreadsheets.Get
Sheets.Spreadsheets.Get setRanges
Sheets.Spreadsheets.Get setIncludeGridData
Class Sheet
Class GridData
Class RowData
Class CellData
Class CellFormat
Class TextFormat
I'm using Google API in Java and have the following code snippets.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
import java.lang.Object;
import java.util.ArrayList;
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.Drive.Files;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
public class DriveQuickstart {
private static final String APPLICATION_NAME = "DriveQuickstart";
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 = "C:/Quickstart/src/main/resources/client_secret.json";
// * Creates an authorized Credential object.
// * #param HTTP_TRANSPORT The network HTTP Transport.
// * #return An authorized Credential object.
// * #throws IOException If the client_secret.json file cannot be found.
// */
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
// Load client secrets.
InputStream in = new FileInputStream(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 {
try
{
// Build a new authorized API client service.
System.out.println("This is a test line");
//declare final variable NetHttpTransport and GoogleNetHttpTransport from import statements
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
System.out.println("This is the second test line");
Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
System.out.println("This is the third test line");
// Print the names and IDs for 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());
}
}
Drive.Files var1 = service.files();
System.out.println("var1 = " + var1.toString());
Drive.Files.List var2 = var1.list();
if (var2 == null)
System.out.println("null");
else {
System.out.printf("Var2 size is: %d\n", var2.size() );
}
//iterate through map and print results
}
catch(Exception e){
System.out.println("error");
}
System.out.println("This is the fourth test line");
}
}
}
To go more into detail. I'm using a somewhat unconventional method to try it. I'm using only command line to run (no IDEs, no gradle).
Here is a link to an ss with my output in command prompt.
cmd output
Assuming that I am actually accessing the metadata in Google Drive, and that the Drive.Files is nested inside an Abstract Map (java.util.AbstractMap), I should be able to return the size of the map to get an idea of where it it searching by how many files it is returning.
I'm not sure what is going on. First time I compile and run, I get the tab opening in chrome asking for permission to gain access to metadata to drive.
Second time, it gives the "WARNING: unable to change permissions for everybody: " errors.
On top of that, var1 ('set to service.files()') returns com.google.api.services.drive.Drive$Files#458ad742 when using toString().
The subclass service.files().list() assigned to var2 should return a list of files in my Google Drive, but apparently it is not doing so.
I may be misunderstanding a lot of stuff, so bear with me. Thanks for the help.
In case people ask, I have tried the tutorial here
https://developers.google.com/drive/api/v3/quickstart/java
It opened the tab to ask for metadata access to google drive on whichever google account I selected.
storedcredential
So from that alone, I (think) connected to Google Drive.
However, the default code that is supposed to list the names and ids of 10 files doesn't do anything.
How am I running the program:
Here is the batch file that I'm using to compile and run the code in cmd.
jar cfe DriveQuickstart.jar Quickstart DriveQuickstart.class
javac -cp ./* DriveQuickstart.java
java -cp ./* DriveQuickstart
For some reason I don't know/understand, this was the only way that wouldn't return methods from the imported jar files not existing.
Familiarize yourself with the Java Quickstart to see how to get the results of the API calls.
Problems
1 - setPermissionsToOwnerOnly
I'm not sure what is going on. First time I compile and run, I get the tab opening in chrome asking for permission to gain access to metadata to drive. Second time, it gives the "WARNING: unable to change permissions for everybody: " errors.
This seems to be related to this issue. It could mean that the folder you are using to run your code from has different permissions than expected.
Does this happen if you place your code on your Desktop (as example) and then run it from there?
2 - toString()
On top of that, var1 ('set to service.files()') returns com.google.api.services.drive.Drive$Files#458ad742 when using toString(). The subclass service.files().list() assigned to var2 should return a list of files in my Google Drive, but apparently it is not doing so.
This weird looking string is how Java prints out an instance of a class.
com.google.api.services.drive.Drive$Files#458ad742
<NAMESPACE>$<CLASS>#<HASHCODE>
The fact that the toString method prints this out means that this method wasn't overwritten for this specific Class, so its calling the general Object.toString() method.
To print out what you want to see, try the nested methods.
I am trying to add code to my android app that gets information from the UI and appends to a file in google drive. I have gotten as far sign in and authorization, as well as querying the file by name. Most of the SO threads I have read are for the old API or REST API.
However, I want to open it in Read/Write, or Write Only mode. I have tried looking at the quickstart demos and the drive API, but none of them are helpful.
How can I get the driveId programatically? I have tried getting the ID from drive itself. Is there a way to build Metadata that gets the ID from the query?
If I use openFile(DriveId.decodeFromString(actual_id).asDriveFile()
I get the following error:
java.lang.IllegalArgumentException: Invalid DriveId: **actual_id**
Is getting the file ID from the sharing link wrong: drive.google.com/open?id=some_id
If so, how can I achieve this?
private String id = "1fuTq1Q6MHrchgW7sZImjvSfpAShHhsbx";
private DriveFile file = DriveId.decodeFromString(id).asDriveFile();
private void getFile() {
Query q = new Query.Builder().addFilter(Filters.and(Filters.eq(SearchableField.TITLE, "HelloWorld.txt"))).build();
}
private void appendFile() {
Task<DriveContents> openTask = getResourceClient().openFile(file, DriveFile.MODE_READ_WRITE);
openTask.continueWithTask(task -> {
DriveContents driveContents = task.getResult();
ParcelFileDescriptor pfd = driveContents.getParcelFileDescriptor();
long bytesToSkip = pfd.getStatSize();
try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
// Skip to end of file
while (bytesToSkip > 0) {
long skipped = in.skip(bytesToSkip);
bytesToSkip -= skipped;
}
}
try (OutputStream out = new FileOutputStream(pfd.getFileDescriptor())) {
out.write("Hello world".getBytes());
}
// [START drive_android_commit_contents_with_metadata]
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setStarred(true)
.setLastViewedByMeDate(new Date())
.build();
Task<Void> commitTask =
getResourceClient().commitContents(driveContents, changeSet);
// [END drive_android_commit_contents_with_metadata]
return commitTask;
})
.addOnSuccessListener(this,
aVoid -> {
//showMessage(getString(R.string.content_updated));
Log.i("DRIVE", "Sucess");
finish();
})
.addOnFailureListener(this, e -> {
Log.e(TAG, "Unable to update contents", e);
// showMessage(getString(R.string.content_update_failed));
finish();
});
}
Also the file exists and the ID is valid.. Apparently
According to the documentation for the GDAA (Google Drive Android API), it should be possible to download a file based on its ID alone by using asDriveFile().
To do that you need a query and then store the information in a Task<MetadataBuffer>, and then should be able to files.get(0).asDriveFile() in the method where you are attempting to download by FileId. But even when pulling the metadata and use the query method, you are greeted with IllegalArgumentException invalid DriveId (which IS THE SAME ID, so it was never invalid), But it STILL shows it as invalid. I got tired of wrestling with it and went to the REST API.
Things to note: The file you are downloading MUST BE: Doc/Spreadsheet/Slides, photo or apps script.
You can choose the type of file you want to export it as. Here is the "truth table" for compatibility.
From this example it is easy enough to write your data and re-upload it. However, these files have a special encoding so you can't write the data directly.
Depending on what you need to accomplish, you can use the sheets api or
apache poi
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [START drive_quickstart]
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
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;
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";
private static String fileId = "super_secret_string";
private static final String OUTPUT = "super_secret_path";
/**
* 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); //DONT USE THIS SCOPE IN PRODUCTION!
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);
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();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).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());
}
}
//Download the file from it's known ID
FileOutputStream fos = new FileOutputStream(OUTPUT);
service.files().export(fileId, "text/plain").executeMediaAndDownloadTo(fos);
//Append some data to the file
FileWriter fw = new FileWriter(OUTPUT, true);
BufferedWriter bw = new BufferedWriter(fw);
bw.newLine();
bw.write("Goodbye, World!");
bw.newLine();
bw.close();
}
}
// [END drive_quickstart]
I went the Java Quickstart and got a working application that just shows the full list of all the users connected to the account logged into. I have gone over the Java docs and the only thing I have found that pertains to the deletion of a user is the "setDeletionTime" in the User class, but I have tried that with a dummy account and set the time to "null" and tried to create a time that was set to today and neither worked for deleting the user. I have no clue what I am missing here.
Code I am using, most of it copied from the google quickstart
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledAp;
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.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.model.*;
import com.google.api.services.admin.directory.Directory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME =
"Directory 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/admin-directory_v1-java-quickstart");
/** 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/admin-directory_v1-java-quickstart
*/
private static final List<String> SCOPES =
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY);
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.
/* This does not work as of now
InputStream in = Quickstart.class.getResourceAsStream("src/resources/client_secret.json");
*/
InputStream in = new FileInputStream("src/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")
.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 Admin SDK Directory client service.
* #return an authorized Directory client service
* #throws IOException
*/
public static Directory getDirectoryService() throws IOException {
Credential credential = authorize();
return new Directory.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
public static void main(String[] args) throws IOException {
// Build a new authorized API client service.
Directory service = getDirectoryService();
// Print the first 10 users in the domain.
Users result = service.users().list().setCustomer("my_customer").setOrderBy("email").execute();
List<User> users = result.getUsers();
if (users == null || users.size() == 0) {
System.out.println("No users found.");
} else {
for (User user : users) {
//This is where I tried to delete the users
//I have also tried using a normal for loop and nothing changes
that
System.out.println();
}
}
}
After reading everything I could find on this that google had to offer I finally figure it out.... I think. I am going to explain it here and have this as the answer because it worked; however, if I am doing something wrong then please tell me. Anyway, here is what I did:
So first thing's first. Every action (as far as I could tell) goes through http as a URL coupled with a command. This means in order for anything to happen you have to have a transport (given by the HttpTransport class) and a factory (given by the HttpRequestFactory class) to create the HttpRequest object that holds the action/command.
The request we will be making is the DELETE request shown here under "Delete a user account"
This can all be done by doing something like this:
HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
HttpRequestFactory HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory();
HttpRequest deleteRequest = HTTP_REQUEST_FACTORY.buildDeleteRequest(new GenericUrl("https://www.googleapis.com/admin/directory/v1/users/userkey"));
BUT WAIT! We are missing a very important key element here. We have to supply the Factory with the correct credentials to mark the header. Basically it is to tell google that we are able to delete the user. So how do we do that?
First we must set the scope, what we want access to. Our scope is ADMIN_DIRECTORY_USER. Set the scope like this: (MAKE SURE YOU DELETE THE FILE IN THE .credentials DIRECTORY IF YOU HAVE ALREADY RAN THIS PROGRAM!!!!)
List<String> SCOPES = Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER);
Next we need to have a credentials object. This can be done by using the method google gives us in their quickstart (the authorize method). To give the credentials to our factory we simply edit the line above by passing it the credentials object:
HttpRequestFactory HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory(credentials);
Note: do not pass it a HttpRequestInitializer from the credentials.getRequestInitializer() method as this is null (At least for me, this could be with just the way I am doing it but I rather not try it).
Here I will attach my code to show you a completed version of this:
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.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
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.admin.directory.DirectoryScopes;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Deleting user example";
/** 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/admin-directory_v1-java-quickstart");
/** 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;
//This creates the factory that is used for the user made requests
private static HttpRequestFactory HTTP_REQUEST_FACTORY;
//This is the credentials for the entire application
private static Credential credential;
/** Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
* at ~/.credentials/admin-directory_v1-java-quickstart
*/
private static final List<String> SCOPES = Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER);
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.
/* This does not work as of now
InputStream in = Quickstart.class.getResourceAsStream("src/resources/client_secret.json");
*/
InputStream in = new FileInputStream("src/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").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
public static void main(String[] args) throws IOException {
System.out.println("Deleting user with email");
credential = authorize();
HTTP_REQUEST_FACTORY = HTTP_TRANSPORT.createRequestFactory(credential);
HttpRequest deleteRequest = HTTP_REQUEST_FACTORY.buildDeleteRequest(new GenericUrl("https://www.googleapis.com/admin/directory/v1/users/REPLACEMEWITHEMAILORUSERKEY"));
deleteRequest.execute();
}
}
I want to fetch google analytics data using google access token, but i didn't find any example , i am getting "Exception in thread
"main" java.net.SocketException: Connection reset"
error , below is the code:-
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
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.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.model.DateRange;
import com.google.api.services.analyticsreporting.v4.model.Dimension;
import com.google.api.services.analyticsreporting.v4.model.GetReportsRequest;
import com.google.api.services.analyticsreporting.v4.model.GetReportsResponse;
import com.google.api.services.analyticsreporting.v4.model.Metric;
import com.google.api.services.analyticsreporting.v4.model.ReportRequest;
public class AnalyticsApiTest {
public static void main(String[] args) throws Exception {
GoogleCredential credential = GoogleCredential
.fromStream(new FileInputStream(new File("d:\\clientsecretnew.json")))
.createScoped(Collections.singleton("https://www.googleapis.com/auth/analytics.readonly"));
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
AnalyticsReporting analyticsReporting = new AnalyticsReporting.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("testing_analytics")
.build();
DateRange dateRange = new DateRange();
dateRange.setStartDate("2017-06-11");
dateRange.setEndDate("2017-06-13");
// Create the Metrics object.
Metric sessions = new Metric()
.setExpression("ga:pageview")
.setAlias("sessions");
//Create the Dimensions object.
Dimension browser = new Dimension()
.setName("ga:browser");
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId("ga:152411###")
.setDateRanges(Arrays.asList(dateRange))
.setDimensions(Arrays.asList(browser))
.setMetrics(Arrays.asList(sessions));
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest()
.setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = analyticsReporting.reports().batchGet(getReport).execute();
}
}
Can anyone tell what is wrong in this??
I think you should try following Googles tutorials. This is the code i use ga:pageview is not a valid metric its ga:pageviews
My Code:
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.auth.oauth2.Credential;
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.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.AnalyticsReportingScopes;
import com.google.api.services.analyticsreporting.v4.model.*;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
/**
* #author Linda Lawton
*/
public class ReportingSample {
/**
* 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 = "DAIMTO Google Analytics Reporting V4 sample";
/** Directory to store user credentials. */
private static final java.io.File DATA_STORE_DIR =
new java.io.File(System.getProperty("user.home"), ".store/reporting_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();
private static AnalyticsReporting service ;
/** 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(ReportingSample.class.getResourceAsStream("/client_secrets.json")));
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(AnalyticsReportingScopes.ANALYTICS_READONLY)).setDataStoreFactory(
dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args) {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
// authorization
Credential credential = authorize();
// set up global Analytics instance
service = new AnalyticsReporting.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(
APPLICATION_NAME).build();
// run commands
fetchData(service);
// success!
return;
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
System.exit(1);
}
public static void fetchData(AnalyticsReporting service) throws IOException{
DateRange dateRange = new DateRange();
dateRange.setStartDate("2017-06-11");
dateRange.setEndDate("2017-06-13");
// Create the Metrics object.
Metric sessions = new Metric()
.setExpression("ga:sessions")
.setAlias("sessions");
//Create the Dimensions object.
Dimension browser = new Dimension()
.setName("ga:browser");
// Create the ReportRequest object.
ReportRequest request = new ReportRequest()
.setViewId("ga:78110423")
.setDateRanges(Arrays.asList(dateRange))
.setDimensions(Arrays.asList(browser))
.setMetrics(Arrays.asList(sessions));
ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request);
// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest()
.setReportRequests(requests);
// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();
}
}