Android數據庫備份和恢復

ygw3 9年前發布 | 4K 次閱讀 Java Android

一定要加上權限,否則不能在sdcard中創建文件
    <!--在sdcard中創建/刪除文件的權限 --> 
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 
    <!--往sdcard中寫入數據的權限 --> 

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


在android手機上將應用的數據庫備份到sdcard,從sdcard中恢復數據庫到應用
直接調用 restoreDB 進行數據庫恢復,調用backupDB進行數據庫備份。
恢復的時候會顯示出可以恢復的數據庫文件列表

 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.AsyncTask; import android.os.Environment; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.view.WindowManager; import android.widget.ProgressBar; import android.widget.Toast;

public class BackupAndRestore { private Context mContext = null; private String[] fileList = null; // 數據庫文件列表 private int choicePostion = -3; // 選擇數據庫列表中的位置 private AlertDialog dialog = null; private String BACK_FOLDER = "backup"; private String appName = "myApp";

public BackupAndRestore(Context context) {
    mContext = context;
}

/**
 * 恢復數據的Dialog
 */
public void restoreDB() {
    fileList = getFileList();
    AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
    builder.setIcon(android.R.drawable.ic_dialog_info);
    builder.setTitle("恢復");
    builder.setSingleChoiceItems(getFileList(), -1, new DialogClick());
    builder.setPositiveButton("確定", new DialogClick());
    builder.setNegativeButton("取消", new DialogClick());
    builder.show();
}

/**
 * 備份數據庫
 */
public void backupDB() {
    showDialog("是否備份數據庫", 'B');
}

/**
 * 顯示一個Dialog
 * 
 * @param title
 *            標題 ,必須引用資源ID resource ID
 * @param sign
 *            根據標示調用方法 I - 恢復默認設置 D - 恢復默認設置 H -選擇主機
 */
private void showDialog(String title, char sign) {
    final char s = sign;
    new AlertDialog.Builder(mContext).setTitle(title)
            .setPositiveButton("確定", new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogI, int which) {
                    switch (s) {
                    case 'B': // 備份數據庫
                        if (dialog == null) {
                            dialog = awaitDialog(mContext);
                        } else {
                            dialog.show();
                        }
                        new ExecuteTask().execute('B');
                        break;
                    default:
                        break;
                    }
                }
            }).setNegativeButton("取消", new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                }
            }).show();
}

/**
 * 備份操作
 * 
 * @return
 */
private boolean backUp() {
    boolean isOk = false;
    String sp = File.separator;
    File sdFile = sdCardOk();
    if (sdFile != null) {
        try {
            String[] dbNames = { "數據庫名稱" };
            // 創建日期文件夾
            String folder_date = datePrefix();
            File f = new File(sdFile.getAbsolutePath() + sp + folder_date);
            if (!f.exists()) {
                f.mkdirs();
            }
            for (int i = 0; i < dbNames.length; i++) {
                String dbName = dbNames[i];
                File dbFile = dbOk(dbName);
                if (dbFile != null) {
                    File backFile = new File(f.getAbsolutePath() + sp
                            + dbFile.getName());
                    backFile.createNewFile();
                    isOk = fileCopy(backFile, dbFile.getAbsoluteFile());
                    if (!isOk) {
                        break;
                    }
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return isOk;
}

/**
 * 時間前綴
 * 
 * @return
 */
private String datePrefix() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    Date date = new Date(System.currentTimeMillis());
    String str = format.format(date);
    return str;
}

/**
 * 文件夾列表
 * 
 * @return
 */
private String[] getFileList() {
    String[] fileList = null;
    File file = sdCardOk();
    if (file != null) {
        File[] list = file.listFiles();
        if (list != null && list.length > 0) {
            fileList = new String[list.length];
            for (int i = 0; i < list.length; i++) {
                fileList[i] = list[i].getName();
            }
        }
    }
    return fileList;
}

/**
 * sdCard是否存在 備份的文件夾是否存在
 * 
 * @return null不能使用
 */
private File sdCardOk() {
    File bkFile = null;
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        String sp = File.separator;
        String backUpPath = Environment.getExternalStorageDirectory() + sp
                + appName + sp + BACK_FOLDER;
        bkFile = new File(backUpPath);
        if (!bkFile.exists()) {
            bkFile.mkdirs();
        } else
            return bkFile;
    } else
        Toast.makeText(mContext, "Sdcard 不存在", Toast.LENGTH_SHORT).show();
    return bkFile;
}

/**
 * 恢復數據庫
 * 
 * @param name
 *            選擇的文件名稱 選中的數據庫名稱
 * @param resoreDbName
 *            需要恢復的數據庫名稱
 * @return
 */
public boolean restore(String name, File f) {
    boolean isOk = false;
    if (f != null) {
        File dbFile = dbOk(name);
        try {
            // System.out.println("覆蓋的名稱"+dbName);
            if (dbFile != null) {
                isOk = fileCopy(dbFile, f.getAbsoluteFile());
            } else
                isOk = false;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return isOk;
}

/**
 * 數據庫文件是否存在,并可以使用
 * 
 * @return
 */
private File dbOk(String dbName) {
    String sp = File.separator;
    String absPath = Environment.getDataDirectory().getAbsolutePath();
    String pakName = mContext.getPackageName();
    String dbPath = absPath + sp + "data" + sp + pakName + sp + "databases"
            + sp + dbName;
    File file = new File(dbPath);
    if (file.exists()) {
        return file;
    } else {
        return null;
    }
}

/**
 * 等候動畫
 */
public AlertDialog awaitDialog(Context context) {
    ProgressBar bar = new ProgressBar(context);
    bar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT));
    AlertDialog dialog = new AlertDialog.Builder(context).create();
    dialog.setCancelable(false);
    dialog.show();
    Window window = dialog.getWindow();
    WindowManager.LayoutParams params = window.getAttributes();
    params.width = 50;
    params.height = 50;
    window.setAttributes(params);
    window.setContentView(bar);
    return dialog;
}

/**
 * 
 * @param outFile
 *            寫入
 * @param inFile
 *            讀取
 * @throws FileNotFoundException
 */
private boolean fileCopy(File outFile, File inFile) throws IOException {
    if (outFile == null || inFile == null) {
        return false;
    }
    boolean isOk = true;
    FileChannel inChannel = new FileInputStream(inFile).getChannel();// 只讀
    FileChannel outChannel = new FileOutputStream(outFile).getChannel();// 只寫
    try {
        long size = inChannel.transferTo(0, inChannel.size(), outChannel);
        if (size <= 0) {
            isOk = false;
        }
    } catch (IOException e) {
        isOk = false;
        e.printStackTrace();
    } finally {
        if (inChannel != null) {
            inChannel.close();
        }
        if (outChannel != null) {
            outChannel.close();
        }
    }
    return isOk;
}

private class DialogClick implements DialogInterface.OnClickListener {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (which == -1) {// 確定
            if (choicePostion < 0) {
                Toast.makeText(mContext, "選擇數據庫", Toast.LENGTH_SHORT)
                        .show();
                return;
            }
            String sp = File.separator;
            String folderName = fileList[choicePostion];
            String backUpPath = Environment.getExternalStorageDirectory()
                    + sp + appName + sp + BACK_FOLDER + sp + folderName;
            File file = new File(backUpPath);
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                boolean isOk = false;
                for (int i = 0; i < files.length; i++) {
                    File f = files[i];
                    isOk = restore(f.getName(), f);
                    if (!isOk) {
                        String fail_msg = "恢復失敗" + ":" + f.getName();
                        Toast.makeText(mContext, fail_msg,
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
                if (isOk) {
                    // 如果有數據體現則需要刷新出新的數據

                }
            }
        } else if (which == -2) {// 取消
        } else if (which >= 0) {
            choicePostion = which;
        }
    }
}

/**
 * 執行任務
 * 
 * @author Administrator
 * 
 */
private class ExecuteTask extends AsyncTask<Character, Void, Boolean> {
    @Override
    protected Boolean doInBackground(Character... params) {
        char c = params[0];
        if (c == 'B') {
            backUp();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        if (dialog != null) {
            dialog.dismiss();
        }
    }
}

}

</pre>

 本文由用戶 ygw3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!