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.
- Android Notepad proveedor classnotfound error ing google drive sdk ejemplos
- Google Drive en error android: java.lang.IllegalArgumentException: el nombre no debe estar vacío: null
- ¿Integración de la unidad de Google en las aplicaciones de Android?
- Archivo de icono de Google Drive. No puedo compilar el proyecto Android de Eclipse
- SDK de Google Drive: carga de imagen, reconocimiento óptico de caracteres, resultado de la descarga
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(); } } }
- Google Drive de Google La carpeta de datos de la aplicación vuelve vacía cuando uso queryChildren
- ¿Cómo configuro Java Doc for google drive api para android en Eclipse
- Nube de Android - Administrador de copia de seguridad vs unidad
- ¿Cómo puedo cambiar cuentas en la NUEVA API de Google Drive para Android?
- Integración de Google Drive en la aplicación de Android, importaciones no resueltas
- Drive API manifiesto e integración con Drive App
- Common_google_play_services_unknown_issue "no se traduce en af, am, ar, be, bg
- ¿Cómo obtener el nombre de archivo y la ruta real del documento de unidad de Google?
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
- Cómo usar blobstore para procesar imágenes de Android
- Manera portable de garantizar que el campo del año de un DateFormat es solamente dos dígitos