Dysk Google do tworzenia kopii zapasowych i przywracania bazy danych oraz wspólnych preferencji aplikacji na Androida
Muszę utworzyć kopię zapasową mojej aplikacji, która obejmowałaby utworzenie kopii zapasowej 2 baz danych, a także współdzielonych preferencji za pomocą Google drive API. Udało mi się wykonać uwierzytelnianie dla aplikacji, a także utworzyć nowy folder na dysku za pomocą następującego kodu:
public class MainActivity2 extends BaseDemoActivity {
DriveId folderId;
@Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
MetadataChangeSet changeSet = new MetadataChangeSet.Builder().setTitle("New folder").build();
Drive.DriveApi.getRootFolder(getGoogleApiClient())
.createFolder(getGoogleApiClient(), changeSet)
.setResultCallback(folderCreatedCallback);
}
ResultCallback<DriveFolderResult> folderCreatedCallback = new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create the folder");
return;
}
folderId = result.getDriveFolder().getDriveId();
showMessage("Created a folder: " + result.getDriveFolder().getDriveId());
}
};
}
Wstawiam plik używając
fileUri = Uri.fromFile(new java.io.File(Environment.getDataDirectory().getPath()
+ "/data/com.example.myapp/databases/mydb.db"));
java.io.File fileContent = new java.io.File(fileUri.getPath());
FileContent mediaContent = new FileContent(getMimeType("db"), fileContent);
File body = new com.google.api.services.drive.model.File();
body.setTitle(fileContent.getName());
body.setMimeType(getMimeType("db"));
File file = service.files().insert(body, mediaContent).execute();
To działa dobrze.
Przywracam używając
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
try {
fileId="0B7Gol85MIbTJLTRxX1hZdDJjaEE";
credential.setSelectedAccountName("the same drive account");
service = getDriveService(credential);
if (fileId != null) {
File file = service.files().get(fileId).execute();
downloadFile(service, file);
}
else return null;
} catch (Throwable tr) {
}
return fileId;
}
private void downloadFile(Drive service, File file) {
InputStream mInput=null;
FileOutputStream mOutput=null;
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp = service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
mInput = resp.getContent();
String outFileName = "file://"+Environment.getDataDirectory().getPath() + "/data/com.example.myapp/databases/InvoiceDataBase.db";
Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath(""));
Log.e("com.example.myapp", "outFileName="+outFileName);
// String outFileName = "../databases/" + "Quickpay.db";
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
// return null;
}
finally {
try {
//Close the streams
if(mOutput != null){
mOutput.close();
}
if(mInput != null){
mInput.close();
}
} catch (IOException e) {
Log.e("com.example.myapp", "failed to close databases");
}
}
} else {
// The file doesn't have any content stored on Drive.
// return null;
Log.e("com.example.myapp", "No content on Drive");
}
}
Kiedy wykonuję kopię zapasową ponownie po przywróceniu, dostaję
" / data/data / com.przykład.myapp / databases/ mydb: open failed: ENOENT (brak takiego pliku lub katalogu)"
Teraz muszę wgrać mój".db " pliku w tym folderze, a także przesłać wspólne Preferencje jako plik XML. Więc moje pytania to:
- jak załadować bazę aplikacji do tego folderu? rozwiązany.
- jak przywrócić plik bazy danych z powrotem do aplikacji?
- czy użytkownik może mieć pełny dostęp do plików po zalogowaniu się na swój dysk Google konto? Czy istnieje inny sposób tworzenia kopii zapasowych i przywracania ? Nie mogę korzystać z "usług kopii zapasowych Androida", ponieważ nie może to być wymuszona kopia zapasowa.
2 answers
Odpowiedź dotyczy zarówno Twojego pliku SQLITE dbase, jak i Twoich współdzielonych Prefs.
Najpierw Zamień wszystko, co chcesz zapisać w bufor bajtu []. Oto przykład dla SQLite dbase:
byte[] getDBBytes() {
Context ctx = getApplicationContext();
byte[] out = null;
try {
File from = ctx.getDatabasePath(ctx.getString(R.string.app_name));
if (from.exists())
out = strm2Bytes(new FileInputStream(from));
} catch (Exception e) {}
return out;
}
(strm2Bytes () jest prymitywem, który kopiuje plik do bufora bajtowego []).
Następnie użyj DEMO ('Tworzenie pliku w folderze', 'Edytuj zawartość' ), aby umieścić dane w pliku dysku. Zachowaj te dwa procesy oddzielnie, ponieważ będziesz aktualizować zawartość tylko wtedy, gdy plik istnieje.
Aby go odzyskać, zacznij od 'Odzyskaj Zawartość ' po prostu zamień BufferBuilder, StringBuilder na własny czytnik InputStream, który wytwarza dane, które umieścisz z powrotem w pliku SQLITE. Coś podobnego do:
public static void setDB(InputStream is) {
Context ctx = getApplicationContext();
try {
File to = ctx.getDatabasePath(ctx.getString(R.string.app_name));
if (to.exists())
to.delete();
strm2File(is, to);
} catch (Exception e) {}
}
Strm2FIle() jest prymitywem, który kopiuje strumień do pliku)
Przepraszam, daję Ci tylko pomysły na wysoki poziom, próbowałem wyciągnąć funkcjonalne fragmenty z mojego kodu, ale jest on tak poplątany, że musiałbym skopiować połowę mojego rzeczy tutaj.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-25 16:31:59
Okazało się, że jedynym problemem było stworzenie pliku przed dodaniem do niego danych. Wywołałem konstruktor mojego dbhelper przed zapisaniem do pliku db.
Zastosowano następujący kod:
java.io.File dir = myContext.getDatabasePath("myDb.db");
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
Dzięki za podjęcie wysiłku, aby pomóc chłopakom !
Na pewno przyjrzę się twojemu SQLiteExample @seanpj. Wrócę, jeśli znajdę lepsze rozwiązanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-26 03:59:12