如何将android数据库sqlite文件复制到sdcard?
我正在尝试将创建的数据库sqlite文件从android内存复制到sdcard,但出现无法复制"错误.有没有一种创建数据库sqlite文件的方法,以便可以轻松地复制它?我需要在设备上的任何地方设置权限吗?
I am trying to copy created database sqlite file from android memory to an sdcard but I am getting "failed to copy" error. Is there a way to create the database sqlite file so it can be easily copied? Do I need to set permissions anywhere on the device?
是的,您确实需要权限,如果少于23,则需要如何依赖于API,那么您需要拥有
Yes you do need permissions and how depends upon the API if less than 23 then you need to have
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在清单(AndroidManifest.xml)中.
in your manifest (AndroidManifest.xml).
如果23或更大,则需要专门要求Accsess.例如在一个活动中(我在MainActivity中拥有此功能,因此始终会对其进行检查)具有:-
If 23 or greater then you need to specifically request Accsess. e.g. In an activity (I have this in MainActivity so it is always checked) have :-
if(Build.VERSION.SDK_INT >= 23) {
ExternalStoragePermissions.verifyStoragePermissions(this);
}
ExternalStoragePermissions类为:-
ExternalStoragePermissions Class is :-
class ExternalStoragePermissions {
public int API_VERSION = Build.VERSION.SDK_INT;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
//Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static final String THISCLASS = ExternalStoragePermissions.class.getSimpleName();
public ExternalStoragePermissions() {}
// Note call this method
public static void verifyStoragePermissions(Activity activity) {
int permission = ActivityCompat.checkSelfPermission(
activity,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
}
这提示用户允许访问.
我都对PS进行了编码,因此应用程序可以应对两种情况.
PS I have both encoded so that the app copes with both situations.
我实际上有一个有效的备份/还原,其中备份是副本.但是,它缠绕了很长一段时间,也许有些令人费解.正如我尝试处理的许多情况一样.我实际上备份到了在downloads文件夹中创建的文件夹.
I do actually have a working backup/restore where a backup is a copy. However, it's quite long winded and perhaps a little convoluted. As I've tried to handle many situations. I actually backup to a folder created in the downloads folder.
如果您有类似SQLite Manager的工具,甚至可以将文件复制到PC上并打开(连接).我用它来测试查询等.您甚至可以修改数据库并将其复制回去(由于还原方面,我可以很容易地做到这一点).我什至不厌其烦地看到如果我复制一个非SQLite文件并从中还原会发生什么情况(基本上可以应付,但确实需要关闭该应用程序然后再打开以规避不可预测的结果).
PS if you have something like SQLite Manager, you can even copy the file to a PC and open it (connect). I use this for testing queries etc. You can even modify the database and copy it back (well I can, very easily, because of the restore side). I've even gone to the lengths of seeing what happens if I copy a non-SQLite file and restore from that (basically it copes but does require the App to be closed and then re-opened to circumvent unpredictable results).
作为长度/卷积的示例,这是我做的第一批检查之一:-
As an example of the length/convolution this is one of the first checks I do :-
// External Storage must be mounted.
String chkmnt = Environment.getExternalStorageState();
if(!(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))) {
switch (Environment.getExternalStorageState()) {
case Environment.MEDIA_SHARED : {
errorlist.add(
"Although External Storage is present." +
" It cannot be used as it's in use via USB." +
"\nDisconnect the USB cable and then try again."
);
break;
}
case Environment.MEDIA_REMOVED : {
errorlist.add(
"External Storage is not present." +
"\nInsert an SC Card."
);
break;
}
case Environment.MEDIA_EJECTING : {
errorlist.add(
"External Storage is being ejected." +
"\nRe-insert the SD Card."
);
break;
}
case Environment.MEDIA_NOFS : {
errorlist.add(
"External Storage is blank or does not have the correct" +
" filesystem present." +
"\nUse a valid SDCard."
);
break;
}
case Environment.MEDIA_BAD_REMOVAL : {
errorlist.add(
"External Storage was removed incorrectly." +
"\nRe-insert the SD Card, if this fails then" +
" try restarting the device."
);
break;
}
case Environment.MEDIA_CHECKING : {
errorlist.add(
"External Storage is unavailable as it is being checked." +
"\nTry again."
);
}
case Environment.MEDIA_MOUNTED_READ_ONLY : {
errorlist.add(
"External Storage is READ ONLY." +
"\nInsert an SD card that is not protected."
);
}
case Environment.MEDIA_UNKNOWN : {
errorlist.add(
"External Storage state is UNKNOWN." +
"\ntry a different SD Card."
);
}
case Environment.MEDIA_UNMOUNTABLE : {
errorlist.add(
"External Storage cannot be mounted." +
"\nTry re-inserting the SD Card or using a different SD Card."
);
}
case Environment.MEDIA_UNMOUNTED : {
errorlist.add(
"External Storage is not mounted." +
"\nTry re-inserting the SD Card or using a different SD Card."
);
}
default: {
errorlist.add(
"Undefined Error"
);
}
}
this.errorcode = UNMOUNTED;
return;
} else {
this.mounted = true;
}
// Get the require directory and specified sub directory
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),subdirectory);
this.directory = dir.getPath();
对于备份本身,我使用:-
For the backup itself I use :-
/**************************************************************************
* method saveDB save a file copy of the Database
*/
private void saveDB() {
busy.show();
errlist.clear();
confirmaction = true;
String dbfilename = this.getDatabasePath(
DBConstants.DATABASE_NAME).getPath();
dbfile = new File(dbfilename);
backupfilename = directory.getText().toString() +
"/" +
backupfullfilename.getText().toString();
new Thread(new Runnable() {
@Override
public void run() {
try {
FileInputStream fis = new FileInputStream(dbfile);
OutputStream backup = new FileOutputStream(backupfilename);
//byte[] buffer = new byte[32768];
int length;
while((length = fis.read(buffer)) > 0) {
backup.write(buffer, 0, length);
}
backup.flush();
backup.close();
fis.close();
}
catch (IOException e) {
e.printStackTrace();
errlist.add("Database backup failed with an IO Error. Error Message was " +
e.getMessage() +
"/n/tFile Name was " +
backupfilename);
confirmaction = false;
}
runOnUiThread(new Runnable() {
@Override
public void run() {
busy.dismiss();
AlertDialog.Builder dbbackupresult = new AlertDialog.Builder(context);
dbbackupresult.setCancelable(true);
if(confirmaction) {
dbbackupresult.setTitle("DB Data Backed up OK.");
dbbackupresult.setMessage("DB Data successfully saved in file \n\t" +
backupfilename );
} else {
dbbackupresult.setTitle("DB Backup Failed.");
String emsg = "";
for(int i = 0; i < errlist.size(); i++) {
emsg = emsg + errlist.get(i);
}
}
dbbackupresult.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
});
}
}).start();
请注意,这些是摘录,可能引用了未包含的代码.例如busy
是进度对话框,directory
是在调用检查例程时填充的EditText
Note these are extracts and may make references to code that is not included. e.g. busy
is a progressdialog, directory
is an EditText
that is populated when the check routine is called