如何为应用程序创建简单的本地备份和恢复?

How to create a simple local backup and restore for an app?

我有五个 sqlite 数据库,我希望用户能够在他的 phone 中进行本地备份,并且他可以恢复备份文件。 我不知道如何创建这些备份并以编程方式恢复它们。 我使用了 A github repo 但它根本不起作用, 我需要你的帮助来创建这个备份和恢复过程。 感谢您的关注

如果清单中有 android:allowBackup="true"

Android 已经支持系统自动备份。如果这还不够,并且您想在应用程序重新安装之间手动管理备份,那么您必须将数据库从 context.getDatabasePath("<your-database-name>") 复制到某个外部存储,然后在需要时将其复制回来

在您的 Activity 制作备份和恢复按钮并定义本地数据库变量,例如,

private MainDatabase localBackup = new MainDatabase(this);

然后点击就可以进行备份和恢复操作

@Override
public void onClick(View v) {
    final MainDatabase db = new MainDatabase(getApplicationContext());

    switch (v.getId()) {
        case R.id.tvBackUp:
            String outFileName = Environment.getExternalStorageDirectory() + 
File.separator + getResources().getString(R.string.app_name) + File.separator;
            localBackup.performBackup(db, outFileName);
            break;
        case R.id.tvRestore:
            File folder = new File(Environment.getExternalStorageDirectory() + File.separator + getApplicationContext().getResources().getString(R.string.app_name));
            if (folder.exists()) {

                final File[] files = folder.listFiles();

                if (files.length == 0) {
                    Toast.makeText(this, "No any Backup", Toast.LENGTH_SHORT).show();
                } else {
                    localBackup.performRestore(db);
                }
            }

            break;
    }
}

在你的数据库文件中创建一个备份方法

public void performBackup(final MainDatabase db, final String outFileName) {

    File folder = new File(Environment.getExternalStorageDirectory() + File.separator 
+ mContext.getResources().getString(R.string.app_name));

    boolean success = true;
    if (!folder.exists())
        success = folder.mkdirs();
    if (success) {

        final Dialog dialog = new Dialog(mContext);
        dialog.setContentView(R.layout.backup_dialog);
        dialog.getWindow().getAttributes().windowAnimations = 
R.style.PauseDialogAnimation;

dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
        dialog.show();

        Button btnSave = dialog.findViewById(R.id.btnSave);
        Button btnCancel = dialog.findViewById(R.id.btnCancel);
        EditText etName = dialog.findViewById(R.id.etName);
        etName.setInputType(InputType.TYPE_CLASS_TEXT);
        btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String m_Text = etName.getText().toString();
                String out = outFileName + m_Text + ".db";

                db.backup(out);
                dialog.dismiss();
            }
        });
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
    } else
        Toast.makeText(mContext, "Unable to create directory. Retry", 
Toast.LENGTH_SHORT).show();
}

    public void backup(String outFileName) {

    //database path
    final String inFileName = mContext.getDatabasePath(DATABASE_NAME).toString();

    try {
        File dbFile = new File(inFileName);
        FileInputStream fis = new FileInputStream(dbFile);

        // Open the empty db as the output stream
        OutputStream output = new FileOutputStream(outFileName);

        // Transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        // Close the streams
        output.flush();
        output.close();
        fis.close();

        Toast.makeText(mContext, "Backup Completed", Toast.LENGTH_SHORT).show();

    } catch (Exception e) {
        Toast.makeText(mContext, "Unable to backup database. Retry", 
Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}

以及恢复做这件事, 询问用户要恢复什么备份

public void performRestore(final MainDatabase db) {


    File folder = new File(Environment.getExternalStorageDirectory() + File.separator 
+ mContext.getResources().getString(R.string.app_name));
    if (folder.exists()) {

        final File[] files = folder.listFiles();

        final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(mContext, 
 android.R.layout.select_dialog_item);
        for (File file : files)
            arrayAdapter.add(file.getName());
        AlertDialog.Builder builderSingle = new AlertDialog.Builder(mContext);

        builderSingle.setTitle("Select & Restore ");
        builderSingle.setNegativeButton("cancle", (dialog, which) -> 
dialog.dismiss());
        builderSingle.setAdapter(arrayAdapter, (dialog, which) -> {
            try {
                db.importDB(files[which].getPath());
            } catch (Exception e) {
                Toast.makeText(mContext, "Unable to restore. Retry", 
Toast.LENGTH_SHORT).show();
            }
        });

        builderSingle.show();
    } else
        Toast.makeText(mContext, "Backup folder not present.\nDo a backup before a 
restore!", Toast.LENGTH_SHORT).show();
}

 public void importDB(String inFileName) {

    final String outFileName = mContext.getDatabasePath(DATABASE_NAME).toString();

    try {

        File dbFile = new File(inFileName);

        FileInputStream fis = new FileInputStream(dbFile);

        // Open the empty db as the output stream
        OutputStream output = new FileOutputStream(outFileName);

        // Transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }

        // Close the streams
        output.flush();
        output.close();
        fis.close();

        Toast.makeText(mContext, "Restore Completed", Toast.LENGTH_SHORT).show();

    } catch (Exception e) {
        Toast.makeText(mContext, "Unable to import database. Retry", 
Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}