简体   繁体   中英

Drive API for Android: App folder not getting sync

I'm trying using the Google API for Android to create a file, search , download and delete in the app folder .

But i'm getting some problems... If i use the ' getRootFolder() ' to save my file everything works. But, if i use ' getAppFolder() ' nothing works.

Example:

  1. The user download my app, my app search if exist any created file.

  2. If nothing return the app create a new file in AppFolder.

  3. If the user uninstall the app and download again, the app can't reach the file.

I try ' requestSync ' but nothing happens. I trying using the Listening for Changes and Receiving completion Events , they return 'Success' but still not sync the AppFolder.

I saw some similar problems, but none works for me.

If i use the 'getRootFolder()' everything works great...

Can you guys help?

Here some Code Examples:

OnConnected:

@Override
public void onConnected(Bundle connectionHint) {
    super.onConnected(connectionHint);
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    if (sharedPreferences.getBoolean("automaticBackup", true)) {
        String FILE_PATH = this.getDatabasePath(DataHelper.DATABASE_NAME).getPath();
        String extension = MimeTypeMap.getFileExtensionFromUrl(FILE_PATH);
        type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        file = new File(FILE_PATH);

        if (hasInternetAccess()) {
            if (sharedPreferences.getBoolean("firstUse", true)) {
                Drive.DriveApi.query(getGoogleApiClient(), query).setResultCallback(restoreCallBack);
                final SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putBoolean("firstUse", false);
                editor.apply();
            } else {
                // delete existing backup
                Drive.DriveApi.query(getGoogleApiClient(), query).setResultCallback(checkIfFileExists);
            }
        }
    }
}

Here i check if file exist, true delete, false create a new one:

final private ResultCallback<DriveApi.MetadataBufferResult> checkIfFileExists = new ResultCallback<DriveApi.MetadataBufferResult>() {

    private DriveId fileId;

    @Override
    public void onResult(@NonNull DriveApi.MetadataBufferResult result) {
        if (!result.getStatus().isSuccess()) {
            showMessage("Problem while checking if file exists...");
            return;
        }

        MetadataBuffer metadata = result.getMetadataBuffer();
        if (metadata.getCount() > 0) {
            fileId = metadata.get(0).getDriveId();
            if (fileId != null) {
                Drive.DriveApi.fetchDriveId(getGoogleApiClient(), fileId.getResourceId()).setResultCallback(deleteFile);
            }
        } else {
            Log.d(TAG, "No backup file found");
            // create new contents resource
            Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(createBackupCallBack);
        }
    }
};

Here the code to delete:

final private ResultCallback<DriveApi.DriveIdResult> deleteFile = new ResultCallback<DriveApi.DriveIdResult>() {

    @Override
    public void onResult(@NonNull DriveApi.DriveIdResult driveIdResult) {
        final DriveId driveId = driveIdResult.getDriveId();

        try {
            new AsyncTask<Void, Void, String>() {
                @Override
                protected String doInBackground(Void... params) {
                    DriveId fileId = DriveId.decodeFromString(driveId.encodeToString());
                    DriveFile driveFile = fileId.asDriveFile();
                    com.google.android.gms.common.api.Status deleteStatus = driveFile.delete(getGoogleApiClient()).await();
                    if (!deleteStatus.isSuccess()) {
                        Log.e(TAG, "Unable to delete the old backup");
                        return null;
                    }
                    sharedPreferences.edit().remove(driveId.toString()).apply();
                    Log.d(TAG, "Removed old backup.");
                    return null;
                }

                @Override
                protected void onPostExecute(String s) {
                    super.onPostExecute(s);
                    // create new contents resource
                    Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(createBackupCallBack);
                }
            }.execute().get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }
    }
};

Upload the file to Drive:

final private ResultCallback<DriveApi.DriveContentsResult> createBackupCallBack = new
        ResultCallback<DriveApi.DriveContentsResult>() {

            @Override
            public void onResult(@NonNull DriveApi.DriveContentsResult result) {
                if (!result.getStatus().isSuccess()) {
                    showMessage("Error while trying to create new file contents");
                    return;
                }
                final DriveContents driveContents = result.getDriveContents();

                new AsyncTask<Void, Void, String>() {
                    @Override
                    protected String doInBackground(Void... params) {

                        OutputStream outputStream = driveContents.getOutputStream();

                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        try {
                            BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
                            while ((bytesRead = inputStream.read(buffer)) != -1) {
                                outputStream.write(buffer, 0, bytesRead);
                            }
                            outputStream.flush();
                            outputStream.close();
                            inputStream.close();
                        } catch (IOException e) {
                            Log.e(TAG, e.getMessage());
                        }

                        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                                .setTitle(DataHelper.DATABASE_NAME)
                                .setMimeType(type)
                                .setStarred(true).build();

                        Drive.DriveApi.getAppFolder(getGoogleApiClient())
                                .createFile(getGoogleApiClient(), changeSet, driveContents)
                                .setResultCallback(fileCallback);
                        return null;
                    }
                }.execute();
            }
        };

Result Call Back from upload:

final private ResultCallback<DriveApi.MetadataBufferResult> restoreCallBack = new ResultCallback<DriveApi.MetadataBufferResult>() {

    DriveId driveId;

    @Override
    public void onResult(@NonNull DriveApi.MetadataBufferResult result) {
        if (!result.getStatus().isSuccess()) {
            showMessage("Problem while restoring...");
        }

        MetadataBuffer metadata = result.getMetadataBuffer();
        if (metadata.getCount() > 0) {
            File fileBD = getDatabasePath(DataHelper.DATABASE_NAME);
            boolean deleted = fileBD.delete();
            Log.d("DELETED", deleted + "");
            driveId = metadata.get(0).getDriveId();
            Drive.DriveApi.fetchDriveId(getGoogleApiClient(), driveId.getResourceId()).setResultCallback(idCallback);
        } else {
            Log.d(TAG, "No backup file found!");
        }
    }
};

It may be permission issue. Adding drive.appfolder authorization scopes to GoogleApiClient may solve your problem. For example:

mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Drive.API)
            .addScope(Drive.SCOPE_APPFOLDER) // required to access app folder
            .addOnConnectionFailedListener(this)
            .addConnectionCallbacks(this)
            .build();
    mGoogleApiClient.connect();

Found a solution, you need to sync with the drive before querying the AppFolder.

Use this after connecting to the drive:

Drive.DriveApi.requestSync(mGoogleApiClient).setResultCallback(new ResultCallback<Status>() {
    @Override
    public void onResult(@NonNull Status status) {

    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM