Я хотел бы добавить функцию в свое приложение для Android, которое автоматически создает резервную копию SQLite в SD-карта.
Какой лучший способ сделать это? Доступны ли какие-либо примеры или учебные пособия?
Я хотел бы добавить функцию в свое приложение для Android, которое автоматически создает резервную копию SQLite в SD-карта.
Какой лучший способ сделать это? Доступны ли какие-либо примеры или учебные пособия?
Базы данных 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
сообщит вам, где находится файл, или сообщит вам, что не так, когда оно не работает.
I ответил на вопрос, подобный этому, с помощью метода, который вы можете разместить в своем SQLiteOpenHelper
. Это так же просто, как копирование db файла из какого-либо внешнего хранилища во внутреннее хранилище приложений. Также есть дополнительный код, который открывается и читает файл db, чтобы убедиться, что он находится в правильном состоянии для 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, но не забывайте изменять Context.MODE_PRIVATE в Context.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}");
Он предоставит вам путь к базе данных. Лучше использовать это вместо hardcoding String, например:
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();
}
}
Если блок успеха дает мне ошибку:
String inFileName = context.getDatabasePath(DB-Name);
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);