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

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.myapp/databases/mydb:打开失败:ENOENT(没有这样的文件或目录)”

现在,我需要在此文件夹中上传“.db”文件,还需要将共享首选项作为XML文件上传。所以我的问题是:
  • 如何将我的应用程序数据库上传到此文件夹? 解决了。
  • 如何将数据库文件还原回应用程序?
  • 用户登录到Google云端硬盘帐户后,可以完全访问这些文件吗?还有其他备份和还原方式吗?我不能使用“Android备份服务”,因为它不能是强制备份。

  • TIA。

    最佳答案

    答案适用于您的SQLite dbase文件和共享的Prefs。

    首先,将任何要保存的内容放入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('Create a file in a folder''Edit contents')将数据放入驱动器文件中。将这两个过程分开,因为仅在文件存在时才更新内容。

    要取回它,请从“Retrieve contents”开始,只需将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()是将流复制到文件中的原语)

    抱歉,我仅向您提供高层次的想法,我试图从代码中提取功能性片段,但由于如此纠结,我不得​​不在这里复制一半的内容。

    07-28 02:59
    查看更多