Reputation: 56
I created a backup of an SQLite database in Android and want to synchronize this to Google Drive. The backup is not synchronized and there is no error from the following code:
public class Synchorize extends Activity {
static final int REQUEST_ACCOUNT_PICKER = 1;
static final int REQUEST_AUTHORIZATION = 2;
private static Drive service;
private static Uri fileUri;
private GoogleAccountCredential credential;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.synchronize);
credential = GoogleAccountCredential.usingOAuth2(this,
Arrays.asList(DriveScopes.DRIVE));
startActivityForResult(credential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
@Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null
&& data.getExtras() != null) {
String accountName = data
.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
service = getDriveService(credential);
saveFileToDrive();
}
}
break;
}
}
private Drive getDriveService(GoogleAccountCredential credential) {
return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
}
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
// File's binary content
fileUri = Uri
.fromFile(new java.io.File(
Environment.getDataDirectory().getPath()
+ "/data/com.example.note_taking/databases/notes.db"));
java.io.File fileContent = new java.io.File(fileUri.getPath());
FileContent mediaContent = new FileContent(getMimeType("db"), fileContent);
// File's metadata.
com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
body.setTitle(fileContent.getName());
body.setMimeType(getMimeType("db"));
com.google.api.services.drive.model.File file = service
.files().insert(body, mediaContent).execute();
if (file != null) {
Toast.makeText(getApplicationContext(),
"Backup Uploaded Successfully",
Toast.LENGTH_LONG).show();
finish();
}
} catch (UserRecoverableAuthIOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
public String getMimeType(String url) {
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
url);
return mimeType;
}
}
Upvotes: 2
Views: 2630
Reputation: 137727
If the SQLite database is not held open by a connection (in any process), it's just an ordinary file and can be copied around just like any other ordinary file. If the SQLite database is held open by a connection but there are no transactions (especially not updates) in progress, you should also have no problems backing it up like this.
Where things get scary is when you have transactions open where those transactions are performing updates. In particular, you would be relying on being able to get the DB in a consistent state in the future despite the backup happening “at a random time” with respect to the writes to the file. That's… unadvisable. You're better off connecting, attaching a backup DB file, opening your own transaction, and then copying the data within the transaction to the other DB. Then, once you commit the transaction, you can safely copy the backup DB file around as you can be fairly sure that nothing else will have a connection open on it. The main downside of this is that you'll have a relatively long transaction open on the DB, but SQLite's not got as sophisticated locking model as a DB server so you're stuck with that; getting the advantage of an in-process DB has to come with at least some disadvantages after all.
Upvotes: 2