我从 Here 下载此演示:
适用于本地备份。但不适用于Google云端硬盘。我选择了gmail gmail帐户,该操作花了一些时间,但数据库未上传到Google驱动器上。
Code:
public class RemoteBackup {
private static final String TAG = "Google Drive Activity";
private DriveClient mDriveClient;
private DriveResourceClient mDriveResourceClient;
public TaskCompletionSource<DriveId> mOpenItemTaskSource;
private MainActivity activity;
public RemoteBackup(MainActivity activity) {
this.activity = activity;
}
public void connectToDrive(boolean backup) {
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(activity);
if (account == null) {
signIn();
} else {
//Initialize the drive api
mDriveClient = Drive.getDriveClient(activity, account);
// Build a drive resource client.
mDriveResourceClient = Drive.getDriveResourceClient(activity, account);
if (backup)
startDriveBackup();
else
startDriveRestore();
}
}
private void signIn() {
Log.i(TAG, "Start sign in");
GoogleSignInClient GoogleSignInClient = buildGoogleSignInClient();
activity.startActivityForResult(GoogleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
private GoogleSignInClient buildGoogleSignInClient() {
GoogleSignInOptions signInOptions =
new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.build();
return GoogleSignIn.getClient(activity, signInOptions);
}
private void startDriveBackup() {
mDriveResourceClient
.createContents()
.continueWithTask(
task -> createFileIntentSender(task.getResult()))
.addOnFailureListener(
e -> Log.w(TAG, "Failed to create new contents.", e));
}
private Task<Void> createFileIntentSender(DriveContents driveContents) {
final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
try {
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
OutputStream outputStream = driveContents.getOutputStream();
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setTitle("database_backup.db")
.setMimeType("application/x-sqlite3")
.build();
CreateFileActivityOptions createFileActivityOptions =
new CreateFileActivityOptions.Builder()
.setInitialMetadata(metadataChangeSet)
.setInitialDriveContents(driveContents)
.build();
return mDriveClient
.newCreateFileActivityIntentSender(createFileActivityOptions)
.continueWith(
task -> {
activity.startIntentSenderForResult(task.getResult(), REQUEST_CODE_CREATION, null, 0, 0, 0);
return null;
});
}
private void startDriveRestore() {
pickFile()
.addOnSuccessListener(activity,
driveId -> retrieveContents(driveId.asDriveFile()))
.addOnFailureListener(activity, e -> {
Log.e(TAG, "No file selected", e);
});
}
private void retrieveContents(DriveFile file) {
//DB Path
final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
Task<DriveContents> openFileTask = mDriveResourceClient.openFile(file, DriveFile.MODE_READ_ONLY);
openFileTask
.continueWithTask(task -> {
DriveContents contents = task.getResult();
try {
ParcelFileDescriptor parcelFileDescriptor = contents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor.getFileDescriptor());
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(inFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fileInputStream.close();
Toast.makeText(activity, "Import completed", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(activity, "Error on import", Toast.LENGTH_SHORT).show();
}
return mDriveResourceClient.discardContents(contents);
})
.addOnFailureListener(e -> {
Log.e(TAG, "Unable to read contents", e);
Toast.makeText(activity, "Error on import", Toast.LENGTH_SHORT).show();
});
}
private Task<DriveId> pickItem(OpenFileActivityOptions openOptions) {
mOpenItemTaskSource = new TaskCompletionSource<>();
mDriveClient
.newOpenFileActivityIntentSender(openOptions)
.continueWith((Continuation<IntentSender, Void>) task -> {
activity.startIntentSenderForResult(
task.getResult(), REQUEST_CODE_OPENING, null, 0, 0, 0);
return null;
});
return mOpenItemTaskSource.getTask();
}
private Task<DriveId> pickFile() {
OpenFileActivityOptions openOptions =
new OpenFileActivityOptions.Builder()
.setSelectionFilter(Filters.eq(SearchableField.MIME_TYPE, "application/db"))
.setActivityTitle("Select DB File")
.build();
return pickItem(openOptions);
}
}
我尝试解决此问题,但没有成功。我也将 MimeType
"application/db"
更改为 "application/x-sqlite3"
,但是没有用。
如果有人知道,请帮助我。
预先感谢:)