使用Google Drive API for Android和堆棧溢出的一些答案,我設法將Google Sign-In應用到我的應用中,並將存儲在用戶設備上的SQLite數據庫備份到Google Drive。使用Google Drive Android API更新SQLite數據庫
僅供參考,這裏是我的數據庫保存到谷歌驅動器(這是在一個名爲DriveDbHandler
final 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 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");
}
});
}
因此,這裏是我的問題:
我可以將數據庫保存到Google雲端硬盤,但是如何更新Google雲端硬盤版本並進行本地更改?
例如,我可以從表A中刪除3行,然後在本地向表B添加5行(到設備的SQLite數據庫),但是如何更新帶有此更改的Google Drive版本?
我曾考慮刪除整個Drive文件並重新上傳,但這會導致該文件的其他DriveId
,這是我的理解。
我想知道我是否能夠利用API的修改處理(解釋here),如果設備沒有互聯網連接,更改將排隊上傳。
當你使用數據庫作爲文件時,我不認爲這個問題有任何簡單/優雅的解決方案 – Distjubo
儘管可以計算出一個[工具](https://sqlite.org/sqldiff.html) 2 sqlite數據庫之間的差異 – Distjubo
@Distjubo是的,這就是我懷疑的。你有沒有我可以使用的解決方案(不管它有多麼優雅)。我將如何使用您建議的_sqldiff_工具? –