我想在我的 Android 应用程序中添加一个功能,自动将SQLite数据库备份到SD 卡。
解决这个问题的最佳方法是什么?是否有可用的示例或教程?
这段代码对我有用!
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) {
}
有谁知道这是否适用于非root手机?我只在有根的 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
哪里,或者在它不起作用时告诉您出了什么问题。
SQLite 数据库是完全独立的文件并且是可移植的——你可以直接将整个文件复制到 SD 卡上。
虽然首先我会检查设备中是否安装了 SD 卡,以及它的路径是什么(使用Environment.getExternalStorageDirectory()
)。
我用一种你可以放在你的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.permission.WRITE_EXTERNAL_STORAGE
。它在无根设备上运行良好。
我不知道如果手机是否已植根会发生什么,但您应该将文件写入:
/Android/data/{package_name}/files/
无论是否扎根,这都会起作用。
如果您是新手,您可以在数据库适配器中找到您的数据库名称。
请注意,您也可以对 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}");
它会给你你的数据库路径。最好使用它而不是硬编码路径,例如:
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();
}
}