谷歌驱动器备份和恢复数据库和Android应用程序的共享偏好



我需要创建应用程序的备份,其中包括创建2个数据库的备份,以及使用Google驱动器API的共享首选项。我能够完成应用程序的身份验证,并使用以下代码在Drive中创建一个新文件夹:

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());
}
};
}

我使用插入文件

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();

这很好用。

我使用恢复

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");
}
}

当我在恢复后再次备份时,我会得到

"/data/data/com.example.myap/databases/mydb:打开失败:ENOENT(没有这样的文件或目录)">

现在,我需要在这个文件夹中上传我的".db"文件,并将共享首选项作为XML文件上传。所以我的问题是:

  1. 如何将应用程序数据库上载到此文件夹已解决
  2. 如何将数据库文件还原回应用程序
  3. 当用户登录到他的Google Drive帐户时,他可以完全访问这些文件吗?是否有其他备份和恢复方法?我不能使用"Android备份服务",因为这不能是强制备份

TIA。

答案适用于您的SQLite数据库文件和共享首选项。

首先,将要保存的任何内容都转换为byte[]缓冲区。以下是SQLite数据库的一个示例:

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()是一个将文件复制到byte[]缓冲区的基元)。

然后使用DEMO("在文件夹中创建文件"、"编辑内容")将数据放入驱动器文件中。将这两个过程分开,因为只有在文件存在的情况下才会更新内容。

要恢复它,请从"检索内容"开始,只需将BufferBuilder、StringBuilder替换为您自己的InputStream读取器,该读取器将生成放回SQLite文件中的数据。类似于:

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()是一个将流复制到文件中的原语)

对不起,我只给你一些高级的想法,我试图从我的代码中提取功能片段,但它太复杂了,我不得不在这里复制一半的东西。

事实证明,唯一的问题是在实际添加数据之前创建文件。在写入数据库文件之前调用了我的dbhelper的构造函数。

使用了以下代码:

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();

谢谢你为帮助大家付出的努力!

我一定会看看你的SQLiteExample@seanpj。如果我发现这是一个更好的解决方案,我会回来的。

相关内容

最新更新