Uso de Google Drive para realizar copias de seguridad y restaurar bases de datos SQLite

He conseguido crear una copia de seguridad de mi base de datos en una tarjeta SD y restaurar desde allí, pero me di cuenta de que el propósito de mi copia de seguridad es garantizar la seguridad de los datos y en este caso si el dispositivo físico está dañado, perdido o Espontáneamente se quema por lo que la copia de seguridad en la tarjeta SD. Así que tener la copia de seguridad en el mismo lugar que el original en este caso, francamente derrotas el propósito de tener una copia de seguridad.

Así que pensé en usar Google Drive como un lugar más seguro para mantener el archivo db, eso y es gratis. He echado un vistazo a la demostración de inicio rápido de Google, que me ha funcionado bien. Pero todavía no tengo ni idea de cómo hacer esto para mi caso.

He encontrado un poco de código para violar, pero todavía está usando algunos métodos obsoletos y hasta ahora sólo he logrado ejecutarlo cuando se omite el área obsoleta, pero sólo crea un archivo binario en blanco en mi Google Drive, así que creo que el área desaprobada Es donde realmente carga el contenido de la copia de seguridad de la base de datos. Si alguien podría ayudar a que sería muy apreciado.

Lo dejaré abajo abajo en caso de que cualquier persona pueda utilizarlo para explicarme las cosas mejor. También he marcado el método obsoleto a continuación, está cerca del final.

public class ExpectoPatronum extends Activity implements ConnectionCallbacks, OnConnectionFailedListener { private static final String TAG = "MainActivity"; private GoogleApiClient api; private boolean mResolvingError = false; private DriveFile mfile; private static final int DIALOG_ERROR_CODE =100; private static final String DATABASE_NAME = "demodb"; private static final String GOOGLE_DRIVE_FILE_NAME = "sqlite_db_backup"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create the Drive API instance api = new GoogleApiClient.Builder(this).addApi(Drive.API).addScope(Drive.SCOPE_FILE). addConnectionCallbacks(this).addOnConnectionFailedListener(this).build(); } @Override public void onStart() { super.onStart(); if(!mResolvingError) { api.connect(); // Connect the client to Google Drive } } @Override public void onStop() { super.onStop(); api.disconnect(); // Disconnect the client from Google Drive } @Override public void onConnectionFailed(ConnectionResult result) { Log.v(TAG, "Connection failed"); if(mResolvingError) { // If already in resolution state, just return. return; } else if(result.hasResolution()) { // Error can be resolved by starting an intent with user interaction mResolvingError = true; try { result.startResolutionForResult(this, DIALOG_ERROR_CODE); } catch (SendIntentException e) { e.printStackTrace(); } } else { // Error cannot be resolved. Display Error Dialog stating the reason if possible. ErrorDialogFragment fragment = new ErrorDialogFragment(); Bundle args = new Bundle(); args.putInt("error", result.getErrorCode()); fragment.setArguments(args); fragment.show(getFragmentManager(), "errordialog"); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == DIALOG_ERROR_CODE) { mResolvingError = false; if(resultCode == RESULT_OK) { // Error was resolved, now connect to the client if not done so. if(!api.isConnecting() && !api.isConnected()) { api.connect(); } } } } @Override public void onConnected(Bundle connectionHint) { Log.v(TAG, "Connected successfully"); /* Connection to Google Drive established. Now request for Contents instance, which can be used to provide file contents. The callback is registered for the same. */ Drive.DriveApi.newDriveContents(api).setResultCallback(contentsCallback); } final private ResultCallback<DriveApi.DriveContentsResult> contentsCallback = new ResultCallback<DriveApi.DriveContentsResult>() { @Override public void onResult(DriveApi.DriveContentsResult result) { if (!result.getStatus().isSuccess()) { Log.v(TAG, "Error while trying to create new file contents"); return; } String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db"); MetadataChangeSet changeSet = new MetadataChangeSet.Builder() .setTitle(GOOGLE_DRIVE_FILE_NAME) // Google Drive File name .setMimeType(mimeType) .setStarred(true).build(); // create a file on root folder Drive.DriveApi.getRootFolder(api) .createFile(api, changeSet, result.getDriveContents()) .setResultCallback(fileCallback); } }; final private ResultCallback<DriveFileResult> fileCallback = new ResultCallback<DriveFileResult>() { @Override public void onResult(DriveFileResult result) { if (!result.getStatus().isSuccess()) { Log.v(TAG, "Error while trying to create the file"); return; } mfile = result.getDriveFile(); mfile.open(api, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(contentsOpenedCallback); } }; final private ResultCallback<DriveApi.DriveContentsResult> contentsOpenedCallback = new ResultCallback<DriveApi.DriveContentsResult>() { @Override public void onResult(DriveApi.DriveContentsResult result) { if (!result.getStatus().isSuccess()) { Log.v(TAG, "Error opening file"); return; } try { FileInputStream is = new FileInputStream(getDbPath()); BufferedInputStream in = new BufferedInputStream(is); byte[] buffer = new byte[8 * 1024]; DriveContents content = result.getDriveContents(); BufferedOutputStream out = new BufferedOutputStream(content.getOutputStream()); int n = 0; while( ( n = in.read(buffer) ) > 0 ) { out.write(buffer, 0, n); } in.close(); commitAndCloseContents is DEPRECATED -->/**mfile.commitAndCloseContents(api, content).setResultCallback(new ResultCallback<Status>() { @Override public void onResult(Status result) { // Handle the response status } });**/ } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; private File getDbPath() { return this.getDatabasePath(DATABASE_NAME); } @Override public void onConnectionSuspended(int cause) { // TODO Auto-generated method stub Log.v(TAG, "Connection suspended"); } public void onDialogDismissed() { mResolvingError = false; } public static class ErrorDialogFragment extends DialogFragment { public ErrorDialogFragment() {} public Dialog onCreateDialog(Bundle savedInstanceState) { int errorCode = this.getArguments().getInt("error"); return GooglePlayServicesUtil.getErrorDialog(errorCode, this.getActivity(), DIALOG_ERROR_CODE); } public void onDismiss(DialogInterface dialog) { ((ExpectoPatronum) getActivity()).onDialogDismissed(); } } } 

Ambas API utilizadas para acceder a Google Drive se ocupan de un contenido binario. Así que lo único que tienes que hacer es cargar tu archivo DB binario, darle un tipo MIME apropiado y un NOMBRE (título).
La selección de API depende de ti, GDAA se comporta como una entidad 'local' con subidas y descargas manejadas por Google Play Services, REST Api es más de bajo nivel, te da más control, pero tienes que cuidar los problemas de red (wifi Encendido / apagado, etc), es decir, por lo general tienen que construir un servicio de sincronización para hacerlo. Con GDAA se hace para usted por GooPlaySvcs. Pero yo divago.
Puedo señalarle a esta demo GitHub , bastante reciente (GooPlaySvcs 7.00. +), Que utilizo para probar diferentes problemas REST / GDAA. El MainActivity es un poco complicado por el hecho de que permite cambiar entre diferentes cuentas de Google, pero si obtienes estos obstáculos , puedes usar envolturas REST o GDAA CRUD.

Mira esta línea . El buffer de bytes [] contiene datos binarios JPEG y va con el tipo mime "image / jpeg" (y un nombre basado en tiempo). Lo único que tienes que hacer si se carga el archivo DB en un buffer de bytes [] usando una construcción como esta:

  private static final int BUF_SZ = 4096; static byte[] file2Bytes(File file) { if (file != null) try { return is2Bytes(new FileInputStream(file)); } catch (Exception ignore) {} return null; } static byte[] is2Bytes(InputStream is) { byte[] buf = null; BufferedInputStream bufIS = null; if (is != null) try { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); bufIS = new BufferedInputStream(is); buf = new byte[BUF_SZ]; int cnt; while ((cnt = bufIS.read(buf)) >= 0) { byteBuffer.write(buf, 0, cnt); } buf = byteBuffer.size() > 0 ? byteBuffer.toByteArray() : null; } catch (Exception e) {le(e);} finally { try { if (bufIS != null) bufIS.close(); } catch (Exception e) {le(e);} } return buf; } 

No recuerdo el tipo MIME para SQLite DB ahora, pero estoy seguro de que se puede hacer ya que estaba haciendo exactamente eso una vez (el código se ha ido ahora, por desgracia). Y recuerdo que en realidad podría acceder y modificar el DB de SQLite 'en la nube' usando alguna aplicación web.

Buena suerte

ACTUALIZAR:
Después de escribir el discurso anterior, miré la demo de la que hablas. Si lo tienes trabajando, la forma más fácil es en realidad para conectar tu archivo de base de datos aquí , establecer el MIME correcto y que está bien para ir. Te lleva a elegir.
Y para hacer frente a su problema 'desaprobado'. GDAA todavía se está desarrollando y el inicio rápido tiene más de un año de edad. Ese es el mundo en que vivimos 🙂

Debe reemplazar el código obsoleto por:
Contents.commit (api, null);

Consulta https://developer.android.com/reference/com/google/android/gms/drive/DriveContents.html

  • Google Drive OCR Android
  • ¿Cómo subir un archivo db a Google Drive desde la aplicación Android?
  • ¿Cómo configurar proguard para la aplicación de Android con Google Drive SDK?
  • Google Drive + ACTION_GET_CONTENT
  • Sincronización en tiempo real con la aplicación de Android y Google Drive
  • Get filepath desde la unidad de google en Lollipop (MediaStore.MediaColumns.DATA == null)
  • ¿Puedo utilizar Google Drive como base de datos?
  • ¿Cancelar la carga de Google Drive posible?
  • ID de cliente del SDK de Google Drive
  • Abrir un URI de contenido de archivo de Google Drive después de usar KitKat Storage Access Framework
  • Seleccionar la imagen de sdcard y almacenarla en Google Drive
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.