Upload multiple files to Google Drive

2019-08-24 02:48发布

问题:

Up until now I've been using the upload a file to drive demo code. However, for my application I need to be able to upload multiple user selected files with one click of a button. My problem is that instead of upload each file to Drive it will upload the last file selected once for every file thats been selected. I think if I understand it correctly the cause of this has something to do the IntentSender being executed multiple times quickly and returning to the REQUEST_CODE_CREATOR case but I'm unable to see another way to structure the code.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CODE_LAUNCH_MAIN:
            if (resultCode == Activity.RESULT_OK) {
                Bundle bundle = data.getExtras();
                for (int i = 0; i<bundle.size()/2; i++) {
                    file = bundle.getByteArray(DATA+i);
                    directory = new Directory(bundle.getString(PATH+i));
                    Log.i(TAG, bundle.getString(PATH+i) + " extracted");
                    uploadFileToDrive();
                    Log.i(TAG, bundle.getString(PATH+i) + " uploaded");
                }
            }
            Toast.makeText(this, "Finished Uploading", 0).show();
            break;
        case REQUEST_CODE_CREATOR:
            // Called after a file is saved to Drive.
            if (resultCode == RESULT_OK) {
                Log.i(TAG, "Files successfully saved.");
                Toast.makeText(this, "Starting new process", 0).show();
                file = null;
                // Return to the Main UI to select more apps ect.
                startActivityForResult(new Intent(this, MainActivity.class),
                        REQUEST_CODE_LAUNCH_MAIN);
            }
            break;
    }
}

uploadToDrive() method

public void uploadFileToDrive() {
    // Start by creating a new contents, and setting a callback.
    Log.i(TAG, "Creating new contents.");
    Drive.DriveApi.newContents(googleApiClient).setResultCallback(new ResultCallback<DriveApi.ContentsResult>() {

        @Override
        public void onResult(DriveApi.ContentsResult result) {

            if (!result.getStatus().isSuccess()) {
                Log.i(TAG, "Failed to create new contents.");
                return;
            }

            Log.i(TAG, "New contents created.");
            OutputStream outputStream = result.getContents().getOutputStream();

            try {
                outputStream.write(file);
            } catch (IOException e1) {
                Log.i(TAG, "Unable to write file contents.");
            }

            // Create the initial metadata - MIME type and title.
            // Note that the user will be able to change the title later.
            MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                    .setMimeType("application/zip")
                    .setTitle(directory.getZipFileName())
                    .build();

            // Create an intent for the file chooser, and start it.
            IntentSender intentSender = Drive.DriveApi
                    .newCreateFileActivityBuilder()
                    .setInitialMetadata(metadataChangeSet)
                    .setInitialContents(result.getContents())
                    .build(googleApiClient);

            try {
                startIntentSenderForResult(
                        intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
            } catch (IntentSender.SendIntentException e) {
                Log.i(TAG, "Failed to launch file chooser.");
            }
        }
    });
}

回答1:

I think the solution is to make file and directory parameters to the uploadFileToDrive() function. Right now your code is referencing the single global copy of those variables, and the callbacks are likely only firing after the last iteration in the for loop is complete.