Backup/Restore SQLlite Database to Google Drive app folder

落花浮王杯 提交于 2019-11-27 01:26:06

问题


I am trying to incorporate the functionality to backup and restore the app database to google drives app folder (NOT visible to the user). I went through the basic setup guide setup guide given for android and can get the user to authorize the app and reach to the point where onConnected method is being called.

The problem that I am facing is, I am not sure how to go about 'sending' the database file (.db) from device to google drive app folder. Google has shared snippet for creating a new file but that's about it. I did find a previously asked question vaguely similar to what I am looking for Google drive to back up and restore database and shared preferences of Android application but then again not what I am looking for.

Searching google doesn't return any helpful links possibly because this is relatively newer api.

UPDATE 1:

Sharing the onConnected() code,

    public void onConnected(Bundle bundle) {
    Toast.makeText(GoogleSignIn.this, "In onConnected activity", Toast.LENGTH_SHORT).show();

    // Testing to see if database is indeed uploaded to google drive app folder
    String db_name = "XXX_DB";
    String currentDBPath = "/data/" + "com.abc.efg" + "/databases/" + db_name;
    saveToDrive(
            Drive.DriveApi.getAppFolder(mGoogleApiClientDrive),
            "XXX_DB.db",
            "application/x-sqlite3",
            new java.io.File(currentDBPath)
    );
}

UPDATE 2:

The solution shared below works perfectly for uploading database to google drive app folder. For those who might face similar problem try changing the database path to "/data/data/com.abc.efg/databases/" + db_name instead of "/data/com.abc.efg/databases/" + db_name

Next step is to be able to retrieve and restore database from google drive app folder. Shall update this question if I am able to get it working.


回答1:


Assuming, you're have a path to your MyDbFile.db file, you can use a construct like this:

 ... 
 saveToDrive(
   Drive.DriveApi.getAppFolder(getGoogleApiClient()),
   "MyDbFile.db", 
   "application/x-sqlite3",
   new java.io.File("\...\...\...\MyDbFile.db")
 );
 ...

DriveId mDriveId;
/******************************************************************
 * create file in GOODrive
 * @param pFldr parent's ID
 * @param titl  file name
 * @param mime  file mime type  (application/x-sqlite3)
 * @param file  file (with content) to create
 */
void saveToDrive(final DriveFolder pFldr, final String titl,
                 final String mime, final java.io.File file) {
  if (getGoogleApiClient() != null && pFldr != null && titl != null && mime != null && file != null) try {
    // create content from file
    Drive.DriveApi.newDriveContents(getGoogleApiClient()).setResultCallback(new ResultCallback<DriveContentsResult>() {
      @Override
      public void onResult(DriveContentsResult driveContentsResult) {
        DriveContents cont = driveContentsResult != null && driveContentsResult.getStatus().isSuccess() ?
          driveContentsResult.getDriveContents() : null;

        // write file to content, chunk by chunk
        if (cont != null) try {
          OutputStream oos = cont.getOutputStream();
          if (oos != null) try {
            InputStream is = new FileInputStream(file);
            byte[] buf = new byte[4096];
            int c;
            while ((c = is.read(buf, 0, buf.length)) > 0) {
              oos.write(buf, 0, c);
              oos.flush();
            }
          }
          finally { oos.close();}

          // content's COOL, create metadata
          MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(mime).build();

          // now create file on GooDrive
          pFldr.createFile(getGoogleApiClient(), meta, cont).setResultCallback(new ResultCallback<DriveFileResult>() {
            @Override
            public void onResult(DriveFileResult driveFileResult) {
              if (driveFileResult != null && driveFileResult.getStatus().isSuccess()) {
                DriveFile dFil = driveFileResult != null && driveFileResult.getStatus().isSuccess() ?
                  driveFileResult.getDriveFile() : null;
                if (dFil != null) {
                  // BINGO , file uploaded
                  dFil.getMetadata(getGoogleApiClient()).setResultCallback(new ResultCallback<MetadataResult>() {
                    @Override
                    public void onResult(MetadataResult metadataResult) {
                      if (metadataResult != null && metadataResult.getStatus().isSuccess()) {
                        DriveId mDriveId = metadataResult.getMetadata().getDriveId();
                      }
                    }
                  });
                }
              } else { /* report error */     }
            }
          });
        } catch (Exception e) { e.printStackTrace(); }
      }
    });
  } catch (Exception e) { e.printStackTrace(); }
}

/*******************************************************************
 * get file contents
 */
void readFromGooDrive() {
  byte[] buf = null;
  if (getGoogleApiClient() != null && getGoogleApiClient().isConnected()) try {
    DriveFile df = Drive.DriveApi.getFile(getGoogleApiClient(), mDriveId);
    df.open(getGoogleApiClient(), DriveFile.MODE_READ_ONLY, null)
      .setResultCallback(new ResultCallback<DriveContentsResult>() {
      @Override
      public void onResult(DriveContentsResult driveContentsResult) {
        if ((driveContentsResult != null) && driveContentsResult.getStatus().isSuccess()) {
          DriveContents cont = driveContentsResult.getDriveContents();
          // DUMP cont.getInputStream() to your DB file
          cont.discard(getGoogleApiClient());    // or cont.commit();  they are equiv if READONLY
        }
      }
    });
  } catch (Exception e) { e.printStackTrace(); }
}

Good Luck



来源:https://stackoverflow.com/questions/33602812/backup-restore-sqllite-database-to-google-drive-app-folder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!