¿Cómo hago una copia de seguridad de un archivo de base de datos a la tarjeta SD en Android?

Me gustaría agregar una función a mi aplicación de Android que realiza automáticamente una copia de seguridad de la base de datos SQLite en la tarjeta SD .

¿Cuál es la mejor manera de hacerlo? ¿Hay ejemplos o tutoriales disponibles?

Las bases de datos SQLite son archivos completamente autónomos y portátiles: puede copiar el archivo completo directamente en la tarjeta SD.

Aunque primero compruebo si hay una tarjeta SD instalada en el dispositivo y cuál es su ruta (usando Environment.getExternalStorageDirectory() ).

¡Este código funciona para mí!

  try { File sd = Environment.getExternalStorageDirectory(); File data = Environment.getDataDirectory(); if (sd.canWrite()) { String currentDBPath = "//data//{package name}//databases//{database name}"; String backupDBPath = "{database name}"; File currentDB = new File(data, currentDBPath); File backupDB = new File(sd, backupDBPath); if (currentDB.exists()) { FileChannel src = new FileInputStream(currentDB).getChannel(); FileChannel dst = new FileOutputStream(backupDB).getChannel(); dst.transferFrom(src, 0, src.size()); src.close(); dst.close(); } } } catch (Exception e) { } 

¿Alguien sabe si esto funcionará en teléfonos no root? Solo lo he probado en un G1 rooteado.

 try { File sd = Environment.getExternalStorageDirectory(); File data = Environment.getDataDirectory(); if (sd.canWrite()) { String currentDBPath = "//data//"+ packageName +"//databases//"+dbList[0]; String backupDBPath = dbList[0]; File currentDB = new File(data, currentDBPath); File backupDB = new File(sd, backupDBPath); FileChannel src = new FileInputStream(currentDB).getChannel(); FileChannel dst = new FileOutputStream(backupDB).getChannel(); dst.transferFrom(src, 0, src.size()); src.close(); dst.close(); Toast.makeText(getBaseContext(), backupDB.toString(), Toast.LENGTH_LONG).show(); } } catch (Exception e) { Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show(); } 

Eso funciona en oposición a los ejemplos anteriores en los que “/” son “\” desperdiciados 20 minutos de mi vida al descubrir eso, pero realmente debería haberlo visto antes. El Toast le dirá dónde se ha colocado el archivo o le dirá qué ocurre cuando no funciona.

Respondí una pregunta similar a esta con un método que puedes colocar en tu SQLiteOpenHelper . Es tan simple como copiar el archivo db de algún tipo de almacenamiento externo al almacenamiento interno de la aplicación. También hay un código adicional que abre y lee el archivo db para asegurarse de que está en el estado adecuado para que Android realice llamadas a la base de datos.

 public static void BackupDatabase() throws IOException { boolean success =true; File file = null; file = new File(Environment.getExternalStorageDirectory() +"/MOLS_Backup"); if (file.exists()) { success =true; } else { success = file.mkdir(); } if (success) { String inFileName = "/data/data/com.sygic.sdk.demo/databases/MOLS_DB.s3db"; File dbFile = new File(inFileName); FileInputStream fis = new FileInputStream(dbFile); String outFileName = Environment.getExternalStorageDirectory()+"/MOLS_Backup/MOLS_DB.s3db"; // Open the empty db as the output stream OutputStream output = new FileOutputStream(outFileName); // Transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer))>0) { output.write(buffer, 0, length); } output.flush(); output.close(); fis.close(); } } 

No sé qué sucede si el teléfono está rooteado o no, pero debe escribir sus archivos en:

 /Android/data/{package_name}/files/ 

Esto funcionará si está rooteado o no.

Debes otorgar el permiso android.permission.WRITE_EXTERNAL_STORAGE en tu aplicación. Funciona bien en dispositivos sin raíz.

Encuentras tu Nombre de base de datos en el Adaptador de base de datos si eres nuevo en esto.

Tenga en cuenta que también puede hacer esto para SharedPreferences, pero tenga en cuenta que cambie su Context.MODE_PRIVATE a Context.MODE_MULTI_PROCESS.

SharedPreferences_name debe verse así: ExportSP("temp.xml");

 String currentPathForSharedPreferences = "/data/"+ context.getPackageName() +"/shared_prefs/"+ SharedPreferences_name; 

Para exportación

 exportDB("MyDbName"); private void exportDB(String db_name){ File sd = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "Your Backup Folder"+ File.separator ); boolean success = true; if (!sd.exists()) { success = sd.mkdir(); } if (success) { File data = Environment.getDataDirectory(); FileChannel source=null; FileChannel destination=null; String currentDBPath = "/data/"+ context.getPackageName() +"/databases/"+db_name; String backupDBPath = db_name; File currentDB = new File(data, currentDBPath); File backupDB = new File(sd, backupDBPath); try { source = new FileInputStream(currentDB).getChannel(); destination = new FileOutputStream(backupDB).getChannel(); destination.transferFrom(source, 0, source.size()); source.close(); destination.close(); Toast.makeText(this, "Please wait", Toast.LENGTH_SHORT).show(); } catch(IOException e) { e.printStackTrace(); } }} 

Para importación

 importDB("MyDbName"); private void importDB(String db_name){ File sd = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "Your Backup Folder"+ File.separator ); File data = Environment.getDataDirectory(); FileChannel source=null; FileChannel destination=null; String backupDBPath = "/data/"+ context.getPackageName() +"/databases/"+db_name; String currentDBPath = db_name; File currentDB = new File(sd, currentDBPath); File backupDB = new File(data, backupDBPath); try { source = new FileInputStream(currentDB).getChannel(); destination = new FileOutputStream(backupDB).getChannel(); destination.transferFrom(source, 0, source.size()); source.close(); destination.close(); Toast.makeText(this, "Please wait", Toast.LENGTH_SHORT).show(); } catch(IOException e) { e.printStackTrace(); } } 

El código de @ skeniver funciona para mí. Solo quiero agregar lo siguiente:

Utilizar:

 String currentDbPath = getApplicationContext().getDatabasePath("{database name}"); 

Le dará la ruta de su base de datos. Es mejor usar eso en lugar de codificar el camino, como:

 String currentDbPath = "//data//{package name}//databases//{database name}"; 
 @Override protected void onCreate(Bundle savedInstanceState) { try { File sd = Environment.getExternalStorageDirectory(); File data = Environment.getDataDirectory(); if (sd.canWrite()) { String currentDBPath = "//data//"+getPackageName()+"//databases//"+DATABASE_NAME+""; String backupDBPath = "backup.db"; File currentDB = new File(data, currentDBPath); File backupDB = new File(sd, backupDBPath); FileChannel src = new FileInputStream(currentDB).getChannel(); FileChannel dst = new FileOutputStream(backupDB).getChannel(); dst.transferFrom(src, 0, src.size()); src.close(); dst.close(); Toast.makeText(getBaseContext(), backupDB.toString(), Toast.LENGTH_LONG).show(); } } catch (Exception e) { Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show(); } }