Search code examples
androidfile-uploadgoogle-drive-apigoogle-drive-android-api

Android Google Drive API upload file - write content error


I'm trying to upload some file to Google Drive. I have this file inside external storage. So, as I get it, steps to get it done:

  1. Create empty file on Google Drive.
  2. Locate your file on device.
  3. Copy file content's through buffer (by bytes).

I successfully managed to create and locate file, but I cannot correctly edit it's content. And I don't know why - callbacks shows, that I edited file, byt it's on Drive it's empty.

Here's my code for uploading the file:

public class UploadFileActivity extends BaseActivity {

    private final static String TAG = "UploadFileActivity";

    @Override
    public void onConnected(Bundle connectionHint) {
        super.onConnected(connectionHint);


        // create new contents resource.
        Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(driveContentsCallback);
    }

    final private ResultCallback<DriveApi.DriveContentsResult> driveContentsCallback =
            new ResultCallback<DriveApi.DriveContentsResult>() {
                @Override
                public void onResult(DriveApi.DriveContentsResult result) {
                    if (!result.getStatus().isSuccess()) {
                        //if failure
                        showMessage("Error while trying to create new file contents");
                        return;
                    }

                    MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                            .setTitle("editor_backup.xml")
                            .setMimeType("text/xml")
                            .setStarred(true).build();


                    Drive.DriveApi.getRootFolder(getGoogleApiClient())
                            .createFile(getGoogleApiClient(), changeSet, result.getDriveContents())
                            .setResultCallback(fileCallBack);

                }

            };

    final ResultCallback<DriveFolder.DriveFileResult> fileCallBack = new ResultCallback<DriveFolder.DriveFileResult>() {
        @Override
        public void onResult(DriveFolder.DriveFileResult driveFileResult) {

            if (!driveFileResult.getStatus().isSuccess()) {
                Log.v(TAG, "Error while trying to create the file");
                return;
            }
            //Initialize mFile to be processed in AsyncTask
            DriveFile mfile = driveFileResult.getDriveFile();
            new EditContentsAsyncTask(UploadFileActivity.this).execute(mfile);

        }
    };

    public class EditContentsAsyncTask extends ApiClientAsyncTask<DriveFile, Void, Boolean> {

        public EditContentsAsyncTask(Context context) {
            super(context);
        }

        @Override
        protected Boolean doInBackgroundConnected(DriveFile... args) {
            DriveFile file = args[0];
            try {

                DriveApi.DriveContentsResult driveContentsResult = file.open(
                        getGoogleApiClient(), DriveFile.MODE_WRITE_ONLY, null).await();


                if (!driveContentsResult.getStatus().isSuccess()) {
                    return false;
                }

                DriveContents driveContents = driveContentsResult.getDriveContents();



                //edit the outputStream
                String inFileName = Environment.getExternalStorageDirectory().getPath() + "/Android/data/somePath/editor.xml" ;
                File backupFile = new File(inFileName);
                FileInputStream inputStream = new FileInputStream(backupFile);
                BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                byte[] buffer = new byte[8 * 1024];

                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(driveContents.getOutputStream());
                int n = 0;
                while ((n = bufferedInputStream.read(buffer)) > 0) {
                    bufferedOutputStream.write(buffer, 0, n);
                }
                bufferedInputStream.close();


                com.google.android.gms.common.api.Status status =
                        driveContents.commit(getGoogleApiClient(), null).await();
                return status.getStatus().isSuccess();
            } catch (IOException e) {
                Log.e(TAG, "IOException while appending to the output stream", e);
            }
            return false;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if (!result) {
                showMessage("Error while editing contents");
                return;
            }
            showMessage("Successfully edited contents");
        }
    }
}

Can you give me a hint or show me what I am doing wrong? Thank you in advance.


Solution

  • Well, I've found a solution. And, since I haven't found a similar question, I wont'd delete this one, but will give an answer for the sake of future generations :)

    You have to change those lines:

    while ((n = bufferedInputStream.read(buffer)) > 0) {
        bufferedOutputStream.write(buffer, 0, n);
    }
    

    To those:

    while ((n = bufferedInputStream.read(buffer, 0, buffer.length)) > 0) {
        bufferedOutputStream.write(buffer, 0, n);
        bufferedOutputStream.flush();
    }
    

    And what's it.