[英]How to copy android database sqlite file to sdcard?
我正在嘗試將創建的數據庫sqlite文件從android內存復制到sdcard,但出現“無法復制”錯誤。 有沒有一種創建數據庫sqlite文件的方法,以便可以輕松復制它? 我需要在設備上的任何地方設置權限嗎?
是的,您確實需要權限,並且如果少於23,則如何依賴於API,那么您需要擁有
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在清單(AndroidManifest.xml)中。
如果大於或等於23,則需要特別要求Access。 例如,在一個活動中( 我在MainActivity中擁有此功能,因此始終對其進行檢查 )具有:-
if(Build.VERSION.SDK_INT >= 23) {
ExternalStoragePermissions.verifyStoragePermissions(this);
}
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
);
}
}
}
這提示用戶允許訪問。
PS我都進行了編碼,因此該應用程序可以應對兩種情況。
我確實有一個有效的備份/還原,其中備份是副本。 但是,它纏繞了很長一段時間,也許有些混亂。 由於我嘗試處理許多情況。 我實際上備份到在downloads文件夾中創建的文件夾。
PS,如果您擁有類似SQLite Manager的功能,您甚至可以將文件復制到PC上並打開它(連接)。 我用它來測試查詢等。您甚至可以修改數據庫並將其復制回去(由於還原方面,我可以很容易地做到這一點)。 我什至不厭其煩地看到如果我復制一個非SQLite文件並從中還原會發生什么(基本上可以應付,但確實需要關閉該應用程序然后重新打開以規避不可預測的結果)。
作為長度/卷積的一個例子,這是我做的第一批檢查之一:
// 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();
對於備份本身,我使用:-
/**************************************************************************
* 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
是進度EditText
, directory
是在調用檢查例程時填充的EditText
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.