使用 Google 驱动器 Android API 更新 SQLite 数据库

Updating an SQLite database using the Google Drive Android API

使用 Google Drive API for Android 和 Stack Overflow 上的一些答案,我成功实现了 Google 登录到我的应用程序,并将存储在用户设备上的 SQLite 数据库备份到 Google 开车.

作为参考,下面是我如何将数据库保存到 Google 驱动器(这是在名为 DriveDbHandlerfinal class 中完成的):

private static final String LOG_TAG = "DriveDbHandler";

private static final String PACKAGE_NAME = "com.package.example";

private static final String DATABASE_PATH =
        "/data/data/" + PACKAGE_NAME + "/databases/" + DbHelper.DATABASE_NAME;

private static final String FILE_NAME = DbHelper.DATABASE_NAME;
private static final String MIME_TYPE = "application/x-sqlite-3";

private DriveDbHandler() {
}


public static void tryCreatingDbOnDrive(final GoogleApiClient googleApiClient) {
    // We need to check if the database already exists on Google Drive. If so, we won't create
    // it again.

    Query query = new Query.Builder()
            .addFilter(Filters.and(
                    Filters.eq(SearchableField.TITLE, FILE_NAME),
                    Filters.eq(SearchableField.MIME_TYPE, MIME_TYPE)))
            .build();
    DriveFolder appFolder = Drive.DriveApi.getAppFolder(googleApiClient);

    appFolder.queryChildren(googleApiClient, query).setResultCallback(
            new ResultCallback<DriveApi.MetadataBufferResult>() {
                @Override
                public void onResult(@NonNull DriveApi.MetadataBufferResult metadataBufferResult) {
                    if (!metadataBufferResult.getStatus().isSuccess()) {
                        Log.e(LOG_TAG, "Query for " + FILE_NAME + " unsuccessful!");
                        return;
                    }

                    int count = metadataBufferResult.getMetadataBuffer().getCount();

                    Log.d(LOG_TAG, "Successfully ran query for " + FILE_NAME + " and found " +
                            count + " results");

                    if (count > 1) {
                        Log.e(LOG_TAG, "App folder contains more than one database file! " +
                                "Found " + count + " matching results.");
                        return;
                    }

                    // Create the database on Google Drive if it doesn't exist already
                    if (count == 0) {
                        Log.d(LOG_TAG, "No existing database found on Google Drive");
                        saveToDrive(googleApiClient);
                    }
                }
            });
}

private static void saveToDrive(final GoogleApiClient googleApiClient) {
    Log.d(LOG_TAG, "Starting to save to drive...");

    // Create content from file
    Drive.DriveApi.newDriveContents(googleApiClient).setResultCallback(
            new ResultCallback<DriveApi.DriveContentsResult>() {
                @Override
                public void onResult(@NonNull DriveApi.DriveContentsResult driveContentsResult) {
                    if (!driveContentsResult.getStatus().isSuccess()) {
                        Log.w(LOG_TAG, "Drive contents result not a success! " +
                                "Not saving data to drive.");
                        return;
                    }

                    Log.d(LOG_TAG, "Created drive contents for file");
                    createNewFile(googleApiClient, driveContentsResult.getDriveContents());
                }
            });
}

private static void createNewFile(GoogleApiClient googleApiClient, DriveContents driveContents) {
    // Write file to contents (see 
    File file = new File(DATABASE_PATH);
    OutputStream outputStream = driveContents.getOutputStream();
    try {
        InputStream inputStream = new FileInputStream(file);
        byte[] buf = new byte[4096];
        int c;
        while ((c = inputStream.read(buf, 0, buf.length)) > 0) {
            outputStream.write(buf, 0, c);
            outputStream.flush();
        }
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    Log.d(LOG_TAG, "Written file to output stream of drive contents");

    // Create metadata
    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
            .setTitle(FILE_NAME)
            .setMimeType(MIME_TYPE)
            .build();

    // Create the file on Google Drive
    DriveFolder folder = Drive.DriveApi.getAppFolder(googleApiClient);
    folder.createFile(googleApiClient, metadataChangeSet, driveContents).setResultCallback(
            new ResultCallback<DriveFolder.DriveFileResult>() {
        @Override
        public void onResult(@NonNull DriveFolder.DriveFileResult driveFileResult) {
            if (!driveFileResult.getStatus().isSuccess()) {
                Log.w(LOG_TAG, "File did not get created in Google Drive!");
                return;
            }

            Log.i(LOG_TAG, "Successfully created file in Google Drive");
        }
    });
}

所以这是我的问题:

我可以将数据库保存到 Google 驱动器,但是 如何使用本地所做的任何更改更新 Google 驱动器版本?

例如,我可以从 table A 中删除 3 行,然后在本地(到设备的 SQLite 数据库)向 table B 添加 5 行,但是如何更新 Google 有此更改的驱动器版本?

我考虑过删除整个云端硬盘文件并重新上传,但据我所知,这会导致该文件出现不同的 DriveId

我想知道我是否能够利用 API 的修改处理(已解释 here),如果设备没有互联网连接,更改将排队等待上传.

根据 ,Google 驱动器的 android API 已经为您处理差异计算。所以不需要做任何复杂的事情,就像你完全重写那个文件一样使用API。

您可能还想利用 API 的透明离线同步功能。