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
Related
I'm trying to make a basic Java program that creates an all-day event when run and want to use my default all-day reminder settings to get around the lack of an API for creating same-day reminders and it's using the default settings for non-all-day events.
I expected that creating an all-day event using the code at the end would use the default all-day event reminders. I've tried adding the snippet directly below this pertaining to setting the default notifications with no change.
.setReminders(new Event.Reminders()
.setUseDefault(true));
I've also tried changing the standard event reminders to check if that's updating when a new event is created, and it is, so there's not some weird cache thing happening. The last thing I tried was setting the start and end date to the same day, despite that setting them to be offset by one is the recommended way to to an all-day event it made no difference.
I've attached the event code and a couple of pictures showing my reminder settings and the reminders for an event created with the program.
DateTime startDateTime = new DateTime(dateFormat.format(today));
DateTime endDateTime = new DateTime(dateFormat.format(tommorow));
Event event = new Event()
.setSummary("Date " + getDateDifference())
.setDescription("Date " + getDateDifference())
.setStart(new EventDateTime()
.setDate(startDateTime))
.setEnd(new EventDateTime()
.setDate(endDateTime));
https://i.imgur.com/Aphb6JR.png
https://i.imgur.com/Fzkdhok.png
To create an All-day event, you must change startDateTime and endDateTime to be a String instead of a DateTime object otherwise Google Calendar will treat this event as normal event rather than a All-day event.
The String pattern should be "YYYY-MM-DD".
You can also override the event reminders, if needed, by using this following example:
...
EventReminder[] reminderOverrides = new EventReminder[] {
new EventReminder().setMethod("email").setMinutes(24 * 60),
new EventReminder().setMethod("popup").setMinutes(10),
};
Event.Reminders reminders = new Event.Reminders()
.setUseDefault(false)
.setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);
...
See this complete example for more information.
EDIT: Adding a working sample based on Java Calendar Quickstart and this sample
Based on how currently Calendar API handles All-day reminders, the only way to create a same-day reminder is setting a "0 Minutes" override. The reminder will be set to 12AM on the day of the event.
There is an open Feature Request here to add support for All-day events with same day reminders
Complete sample code
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.EventReminder;
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;
import java.util.Arrays;
/* class to demonstarte use of Calendar events list API */
public class CalendarQuickstart {
/**
* Application name.
*/
private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
/**
* Global instance of the JSON factory.
*/
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
/**
* Directory to store authorization tokens for this application.
*/
private static final String TOKENS_DIRECTORY_PATH = "tokens";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final List<String> SCOPES =
Collections.singletonList(CalendarScopes.CALENDAR);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";
/**
* Creates an authorized Credential object.
*
* #param HTTP_TRANSPORT The network HTTP Transport.
* #return An authorized Credential object.
* #throws IOException If the credentials.json file cannot be found.
*/
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT)
throws IOException {
// Load client secrets.
InputStream in = CalendarQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
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();
Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
//returns an authorized Credential object.
return credential;
}
public static void main(String... args) throws IOException, GeneralSecurityException {
// Build a new authorized API client service.
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Calendar service =
new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
.setApplicationName(APPLICATION_NAME)
.build();
Event event = new Event()
.setSummary("Google I/O 2015")
.setLocation("800 Howard St., San Francisco, CA 94103")
.setDescription("A chance to hear more about Google's developer products.");
DateTime startDateTime = new DateTime("2022-11-25");
EventDateTime start = new EventDateTime().setDate(startDateTime);
event.setStart(start);
DateTime endDateTime = new DateTime("2022-11-25");
EventDateTime end = new EventDateTime().setDate(endDateTime);
event.setEnd(end);
EventReminder[] reminderOverrides = new EventReminder[] {
new EventReminder().setMethod("email").setMinutes(0),
};
Event.Reminders reminders = new Event.Reminders()
.setUseDefault(false)
.setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);
String calendarId = "primary";
event = service.events().insert(calendarId, event).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink());
}
}
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();
}
}
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.