0
votes

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?

1
Have you tried manually creating a spreadsheet file and then seeing that the metadata associated with that file is using a get request?dazza5000
I was actually thinking of doing that next. Currently, I am playing around with the REST API for Drive and creating the file that way. It is a lot more involved, and I have yet to get a meaningful result.Jeremy
Thank you. Please report back if you get it.dazza5000
I am currently using this documentation. Specifically, I am using AsyncTask to create the new file. In doInBackground, I am calling a method to create the file which is similar to the main method here. I am getting an IOExeption and do not know how to fix it....Jeremy
I can taste how close I am to getting it right. In my doInBackground method, I am now just having trouble with getting to token associated with the GoogleAccountCredential. I will continue to look into thisJeremy

1 Answers

1
votes

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.