使用Google Drive Android API更新SQLite数据库

使用Google Drive Android API更新SQLite数据库,android,android-sqlite,google-drive-android-api,Android,Android Sqlite,Google Drive Android Api,使用和一些关于堆栈溢出的答案,我成功地在我的应用程序中实现了Google登录,并将存储在用户设备上的SQLite数据库备份到Google Drive 以下是我如何将数据库保存到Google Drive(这是在名为DriveDbHandler的final类中完成的)以供参考: private static final String LOG_TAG=“DriveDbHandler”; 私有静态最终字符串PACKAGE_NAME=“com.PACKAGE.example”; 私有静态最终字符串数据库\

使用和一些关于堆栈溢出的答案,我成功地在我的应用程序中实现了Google登录,并将存储在用户设备上的SQLite数据库备份到Google Drive

以下是我如何将数据库保存到Google Drive(这是在名为
DriveDbHandler
final类中完成的)以供参考:

private static final String LOG_TAG=“DriveDbHandler”;
私有静态最终字符串PACKAGE_NAME=“com.PACKAGE.example”;
私有静态最终字符串数据库\u路径=
“/data/data/”+PACKAGE_NAME+“/databases/”+DbHelper.DATABASE_NAME;
私有静态最终字符串文件\u NAME=DbHelper.DATABASE\u NAME;
私有静态最终字符串MIME_TYPE=“application/x-sqlite-3”;
private-DriveDbHandler(){
}
公共静态无效尝试创建Bondrive(最终GoogleAppClient GoogleAppClient){
//我们需要检查Google Drive上是否已经存在该数据库。如果已经存在,我们将不会创建
//又来了。
Query Query=new Query.Builder()
.addFilter(Filters.and(
Filters.eq(SearchableField.TITLE,文件名),
Filters.eq(SearchableField.MIME\u TYPE,MIME\u TYPE)))
.build();
DriveFolder appFolder=Drive.DriveApi.getAppFolder(GoogleAppClient);
appFolder.queryChildren(GoogleAppClient,query).setResultCallback(
新的ResultCallback(){
@凌驾
public void onResult(@NonNull DriveApi.MetadataBufferResult MetadataBufferResult){
如果(!metadataBufferResult.getStatus().isSuccess()){
e(Log_标签,“查询”+文件名+“未成功!”);
返回;
}
int count=metadataBufferResult.getMetadataBuffer().getCount();
Log.d(Log_标记,“已成功运行对“+文件名+”的查询并找到”+
计数+“结果”);
如果(计数>1){
Log.e(Log_标记,“应用程序文件夹包含多个数据库文件!”+
“找到“+计数+”匹配结果。”);
返回;
}
//在Google Drive上创建数据库(如果该数据库尚不存在)
如果(计数=0){
Log.d(Log_标签,“在谷歌硬盘上找不到现有数据库”);
saveToDrive(GoogleapClient);
}
}
});
}
私有静态无效保存驱动(最终GoogleAppClient GoogleAppClient){
Log.d(Log_标签,“开始保存到驱动器…”);
//从文件创建内容
Drive.DriveApi.newDriveContents(GoogleAppClient.setResultCallback)(
新的ResultCallback(){
@凌驾
public void onResult(@NonNull DriveApi.DriveContentsResult DriveContentsResult){
如果(!driveContentsResult.getStatus().isSuccess()){
w(Log_标记,“驱动器内容结果不成功!”+
“未将数据保存到驱动器。”);
返回;
}
Log.d(Log_标记,“为文件创建的驱动器内容”);
createNewFile(GoogleAppClient,driveContentsResult.getDriveContents());
}
});
}
私有静态void createNewFile(GoogleAppClient GoogleAppClient、DriveContents DriveContents){
//将文件写入目录(请参见http://stackoverflow.com/a/33610727/4230345)
文件=新文件(数据库路径);
OutputStream OutputStream=driveContents.getOutputStream();
试一试{
InputStream InputStream=新文件InputStream(文件);
字节[]buf=新字节[4096];
INTC;
而((c=inputStream.read(buf,0,buf.length))>0){
outputStream.write(buf,0,c);
outputStream.flush();
}
outputStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
Log.d(Log_标记,“写入到驱动器内容输出流的文件”);
//创建元数据
MetadataChangeSet MetadataChangeSet=新建MetadataChangeSet.Builder()
.setTitle(文件名)
.setMimeType(MIME_类型)
.build();
//在谷歌硬盘上创建文件
DriveFolder folder=Drive.DriveApi.getAppFolder(GoogleAppClient);
folder.createFile(GoogleAppClient、metadataChangeSet、driveContents).setResultCallback(
新的ResultCallback(){
@凌驾
public void onResult(@NonNull DriveFolder.DriveFileResult DriveFileResult){
如果(!driveFileResult.getStatus().isSuccess()){
w(Log_标签,“文件未在谷歌硬盘中创建!”);
返回;
}
Log.i(Log_标签,“在谷歌硬盘中成功创建文件”);
}
});
}
这就是我的问题:

我可以将数据库保存到Google Drive,但是如何使用本地更改更新Google Drive版本?

例如,我可以从表A中删除3行,然后在本地(设备的SQLite数据库)向表B添加5行,但是如何使用此更改更新Google Drive版本

我考虑过删除整个驱动器文件并重新上传,但据我所知,这将导致该文件的
DriveId

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

根据,android API for Google Drive已经为您处理了差异计算。因此,不需要做任何复杂的事情,只需使用API,就像完全重写该文件一样

您可能还想利用API透明的脱机同步功能。

我认为没有
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 http://stackoverflow.com/a/33610727/4230345)
    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");
        }
    });
}