Как сделать резервную копию файла базы данных на SD-карту на Android?
Я хотел бы добавить функцию в мое приложение для Android, которая автоматически создает резервную копию SQLite
10 ответов:
базы данных SQLite являются полностью автономными файлами и являются портативными - вы можете просто скопировать весь файл прямо на SD-карту.
хотя сначала я бы проверил, установлена ли SD-карта в устройстве, и каков ее путь (используя
Environment.getExternalStorageDirectory()
).
этот код работает для меня!
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) { }
кто-нибудь знает, будет ли это работать на некорневых телефонах? Я только попробовал его на корневом G1.
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(); }
это работает в отличие от приведенных выше примеров, в которых "/" являются "\" потраченными впустую 20 минут моей жизни, выясняя это, но я действительно должен был увидеть это раньше. Элемент
Toast
скажет вам, где файл был место или сказать вам, что не так, когда он не работает.
Я ответил вопрос, подобный этому, с помощью метода, который вы можете разместить в своем
SQLiteOpenHelper
. Это так же просто, как копирование файла БД из какого-то внешнего хранилища, во внутреннее хранилище приложений. Существует также некоторый дополнительный код, который открывает и читает файл БД, чтобы убедиться, что он находится в правильном состоянии для Android, чтобы сделать вызовы базы данных к нему.
public static void BackupDatabase() throws IOException { boolean success =true; File file = null; file = new File(Environment.getExternalStorageDirectory() +"/M.O.L.S_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()+"/M.O.L.S_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(); } }
Я не знаю, что произойдет, если телефон рутован или нет, но вы должны написать ваши файлы:
/Android/data/{package_name}/files/
Это будет работать независимо от того, укоренен он или нет.
вы должны дать разрешение
android.permission.WRITE_EXTERNAL_STORAGE
в вашем приложении. Он отлично работает на некорневых устройствах.
вы найдете свое имя базы данных в адаптере базы данных, если вы новичок в этом.
обратите внимание, что вы можете сделать это для SharedPreferences тоже, но имейте в виду, чтобы изменить свой контекст.MODE_PRIVATE в контекст.MODE_MULTI_PROCESS.
SharedPreferences_name должно выглядеть так =
ExportSP("temp.xml");
String currentPathForSharedPreferences = "/data/"+ context.getPackageName() +"/shared_prefs/"+ SharedPreferences_name;
для экспорта
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(); } }}
импорт
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(); } }
@skeniver код работает для меня. Я просто хочу добавить следующее:
использование:
String currentDbPath = getApplicationContext().getDatabasePath("{database name}");
это даст вам ваш путь к базе данных. Лучше использовать это вместо жесткого кодирования пути, например:
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(); } }