[英]How to copy android database sqlite file to sdcard?
I am trying to copy created database sqlite file from android memory to an sdcard but I am getting "failed to copy" error. 我正在尝试将创建的数据库sqlite文件从android内存复制到sdcard,但出现“无法复制”错误。 Is there a way to create the database sqlite file so it can be easily copied? 有没有一种创建数据库sqlite文件的方法,以便可以轻松复制它? Do I need to set permissions anywhere on the device? 我需要在设备上的任何地方设置权限吗?
Yes you do need permissions and how depends upon the API if less than 23 then you need to have 是的,您确实需要权限,并且如果少于23,则如何依赖于API,那么您需要拥有
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
in your manifest (AndroidManifest.xml). 在清单(AndroidManifest.xml)中。
If 23 or greater then you need to specifically request Accsess. 如果大于或等于23,则需要特别要求Access。 eg In an activity ( I have this in MainActivity so it is always checked ) have :- 例如,在一个活动中( 我在MainActivity中拥有此功能,因此始终对其进行检查 )具有:-
if(Build.VERSION.SDK_INT >= 23) {
ExternalStoragePermissions.verifyStoragePermissions(this);
}
ExternalStoragePermissions Class is :- ExternalStoragePermissions类是:-
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
);
}
}
}
This prompt the user to allow access. 这提示用户允许访问。
PS I have both encoded so that the app copes with both situations. PS我都进行了编码,因此该应用程序可以应对两种情况。
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. 我实际上备份到在downloads文件夹中创建的文件夹。
PS if you have something like SQLite Manager, you can even copy the file to a PC and open it (connect). PS,如果您拥有类似SQLite Manager的功能,您甚至可以将文件复制到PC上并打开它(连接)。 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). 我什至不厌其烦地看到如果我复制一个非SQLite文件并从中还原会发生什么(基本上可以应付,但确实需要关闭该应用程序然后重新打开以规避不可预测的结果)。
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();
Note these are extracts and may make references to code that is not included. 请注意,这些是摘录,可能引用了未包含的代码。 eg busy
is a progressdialog, directory
is an EditText
that is populated when the check routine is called 例如, busy
是进度EditText
, directory
是在调用检查例程时填充的EditText
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.