如何将android数据库sqlite文件复制到SD卡?

时间:2017-02-02 14:17:49

标签: android android-sqlite

我正在尝试将创建的数据库sqlite文件从android内存复制到sdcard,但我收到“无法复制”错误。有没有办法创建数据库sqlite文件,以便可以轻松复制?我是否需要在设备的任何位置设置权限?

1 个答案:

答案 0 :(得分:1)

是的,你确实需要权限,如果少于23,则取决于API,那么你需要

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
清单中的

(AndroidManifest.xml)。

如果是23或更高,则需要特别要求Accsess。例如在一个活动中(我在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我已编码,以便应用程序可以应对这两种情况。

我确实有一个正常工作的备份/恢复,其中备份是副本。然而,它很长时间啰嗦,也许有点复杂。因为我试图处理很多情况。我实际上备份到下载文件夹中创建的文件夹。

PS如果你有类似SQLite Manager的东西,你甚至可以将文件复制到PC并打开它(连接)。我用它来测试查询等。你甚至可以修改数据库并将其复制回来(我可以,非常容易,因为还原方面)。我甚至不知道如果我复制一个非SQLite文件并从中恢复会发生什么(基本上它应对但是需要关闭然后重新打开才能绕过不可预测的结果)。< / p>

作为长度/卷积的一个例子,这是我做的第一个检查之一: -

    // 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是进度对话,directoryEditText,在调用检查例程时会填充