Reputation: 152
It is my first time working with the Drive and Sheets API, and I am confused about which one should be used when creating a new file. I wish to create a blank google sheets file, saved on a drive, which I can edit programmatically later. To my understanding, the Drive API is used for basic file manipulation; such as creating, deleting, and moving files. While the Sheets API is used for more direct spreadsheet manipulation; being writing data, formatting, and such. Therefore, to create a new spreadsheet file, logic tells me that the Drive API will create the spreadsheet I want. As most of the questions on here are using old iterations of the Drive API, it is difficult (at least for me) to transition those processes to the new API.
I have been following the guide provided on the Drive API documentation. Because I am creating an empty sheets file, I have altered the code by setting the initial drive contents to null, while keeping consistent with the sample. :
CreateFileActivityOptions createOptions =
new CreateFileActivityOptions.Builder()
.setInitialDriveContents(null)
.setInitialMetadata(changeSet)
.build();
return getDriveClient().newCreateFileActivityIntentSender(createOptions);
This is the complete method I used to attempt to create the file:
private void saveFileToDrive(){
Log.i(TAG, "Creating the new file");
DriveResourceClient mDriveResourceClient;
mDriveResourceClient =Drive
.getDriveResourceClient(this,GoogleSignIn.getLastSignedInAccount(this));
mDriveResourceClient.createContents()
.continueWithTask(new Continuation<DriveContents, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<DriveContents> task) throws Exception {
return createFileIntentSender(task.getResult());
};
});
}
private Task<Void> createFileIntentSender(DriveContents driveContents){
Log.i(TAG, "New file being created");
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("New file.xls")
.setMimeType("application/vnd.google-apps.spreadsheet")
.setStarred(true)
.build();
CreateFileActivityOptions createOptions =
new CreateFileActivityOptions.Builder()
.setInitialDriveContents(null)
.setInitialMetadata(changeSet)
.build();
return mDriveClient.newCreateFileActivityIntentSender(createOptions)
.continueWith(
new Continuation<IntentSender, Void>() {
@Override
public Void then(@NonNull Task<IntentSender> task) throws Exception {
return null;
}
}
);
}
I have changed the Mime type to application/vnd.google-apps.spreadsheet so that the new file being created is a spreadsheet. What I don't understand is that when I have a direct implementation of the sample code from the API documentation, the code consistently creates a file. Why won't it create a spreadsheet? Is there something I am missing?
The Sheets API also has a create method to create a new spreadsheet. Is that the correct methodology to follow, rather than through the Drive API?
Upvotes: 0
Views: 1116
Reputation: 152
After a lot of playing around, I have finally been able to create a blank spreadsheet using the Sheets API. What I found confusing when initially reading the Drive and Sheets API (as a newbie to these APIs), is that I understood that the correct workflow for creating new files is through the Drive API, rather than the Sheets API. From what I found, this is incorrect.
I took the sample code provided in the Android quickstart in the Sheets API, and adapted the code from the .create method in the reference documentation. Specifically, I implemented the code to create a new spreadsheet file in the AsyncTask method (MakeRequestTask). What I did is as follows:
private class MakeRequestTask extends AsyncTask<Void, Void, Spreadsheet> {
private com.google.api.services.sheets.v4.Sheets mService = null;
private Exception mLastError = null;
MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new Sheets.Builder(
transport, jsonFactory, credential)
.setApplicationName("Google Sheets API Android Quickstart")
.build();
}
/**
* Background task to call Google Sheets API.
* @param params no parameters needed for this task.
*/
@Override
protected Spreadsheet doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
/**
* Fetch a list of names and majors of students in a sample spreadsheet:
* https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
* @return List of names and majors
* @throws IOException
*/
private Spreadsheet getDataFromApi() throws IOException {
Spreadsheet requestBody = new Spreadsheet();
SpreadsheetProperties properties = new SpreadsheetProperties();
properties.setTitle(title);
requestBody.setProperties(properties);
Sheets.Spreadsheets.Create request = mService.spreadsheets().create(requestBody);
return request.execute();
}
What is not shown here is the declaration of title, which is passed into properties.setTitle(title)
. I declared this in the initial MainActivity class, and set it simply to be private String title = "Sheet Creation Test";
After a couple days of researching and not getting anything, I hope that providing this solution will help anyone who is trying to do the same thing.
Upvotes: 1