先上一个数据库备份工具类:
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
/**
*
* 数据库备份还原类
* Created by Lizhuang on 2016/12/12.
*
* 备份操作
* new DbBackups(this).execute("backupDatabase");
* 还原操作
* new DbBackups(this).execute("restroeDatabase");
*
*/
public class DbBackups extends AsyncTask<String, Void, Integer> {
private static final String COMMAND_BACKUP = "backupDatabase";
public static final String COMMAND_RESTORE = "restroeDatabase";
private static final int BACKUP_SUCCESS = 1;
public static final int RESTORE_SUCCESS = 2;
private static final int BACKUP_ERROR = 3;
public static final int RESTORE_NOFLEERROR = 4;
private Context myContext;
public DbBackups(Context context) {
this.myContext = context;
}
@Override
protected Integer doInBackground(String... params) {
// 需要备份的数据库路径
File dbFile = new File(文件路径, "文件名");
// 创建数据库目录路径 */DoorsDb/*.db
File exportDir = new File(*, "DoorsDB");
if (!exportDir.exists()) {
exportDir.mkdirs();
}
File backup = new File(exportDir, dbFile.getName());
String command = params[0];
if (command.equals(COMMAND_BACKUP)) {
try {
backup.createNewFile();
fileCopy(dbFile, backup);
return BACKUP_SUCCESS;
} catch (Exception e) {
Log.e("DbBackups", "数据库备份异常" + e.getMessage());
return BACKUP_ERROR;
}
} else if (command.equals(COMMAND_RESTORE)) {
try {
fileCopy(backup, dbFile);
return RESTORE_SUCCESS;
} catch (Exception e) {
Log.e("DbBackups", "数据库还原异常" + e.getMessage());
return RESTORE_NOFLEERROR;
}
} else {
return null;
}
}
private void fileCopy(File dbFile, File backup) throws IOException {
FileChannel inChannel = new FileInputStream(dbFile).getChannel();
FileChannel outChannel = new FileOutputStream(backup).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IOException e) {
Log.e("DbBackups", "数据库文件操作异常" + e.getMessage());
} finally {
if (inChannel != null) {
inChannel.close();
}
if (outChannel != null) {
outChannel.close();
}
}
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
switch (result) {
case BACKUP_SUCCESS:
Log.d("数据库备份", "成功");
break;
case BACKUP_ERROR:
Log.d("数据库备份", "失败");
break;
case RESTORE_SUCCESS:
Log.d("数据库还原", "成功");
break;
case RESTORE_NOFLEERROR:
Log.d("数据库还原", "失败");
break;
default:
break;
}
}
}
//数据库定时备份线程实现
DbBackupsThread = new Thread(new Runnable() {
@Override
public void run() {
//数据库备份的时间
Calendar calendar = Calendar.getInstance();
String backupTime = String.valueOf(calendar.get(Calendar.YEAR)) + "-"
+ String.valueOf(calendar.get(Calendar.MONTH) + 1) + "-"
+ String.valueOf(calendar.get(Calendar.DAY_OF_MONTH))
+ " 18:" + "0:" + "0";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
final Calendar backupDate = Calendar.getInstance();
backupDate.setTime(sdf.parse(backupTime));
final Calendar xmlDate = Calendar.getInstance();
xmlDate.setTime(sdf.parse(SharedPreferencesUtil.getData(getApplication(), "DbBackupTime", "1970 -1-1 0:0:0").toString()));
long delay = (sdf.parse(backupTime).getTime() - 28800000) - (new Date().getTime() - 28800000);
long period = 86400000;
if (delay < 0) { //当前时间大于备份时间
delay = 0; //立即执行备份操作
period += delay; //计算时间差
}
timer = new Timer(true);
final Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DAY_OF_MONTH, -1);
yesterday.set(Calendar.HOUR_OF_DAY, 0);
yesterday.set(Calendar.MINUTE, 0);
yesterday.set(Calendar.SECOND, 0);
if (xmlDate.getTime().before(yesterday.getTime())) {
//备份数据库
new DbBackups(getApplication()).execute("backupDatabase");
//更新数据库备份时间
int month = yesterday.get(Calendar.MONTH) + 1;
SharedPreferencesUtil.saveData(getApplication(), "DbBackupTime", "" + yesterday.get(Calenda r.YEAR) + "-" + month + "-" + yesterday.get(Calendar.DAY_OF_MONTH) + " 23:59:59");
xmlDate.setTime(sdf.parse(SharedPreferencesUtil.getData(getApplication(), "DbBackupTime", " 1970-1-1 0:0:0").toString()));
}
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//如果今天有过备份操作就不进行了
if (backupDate.get(Calendar.YEAR) != xmlDate.get(Calendar.YEAR) ||
backupDate.get(Calendar.MONTH) != xmlDate.get(Calendar.MONTH) ||
backupDate.get(Calendar.DAY_OF_MONTH) != xmlDate.get(Calendar.DAY_OF_MONTH) ||
backupDate.get(Calendar.HOUR_OF_DAY) > xmlDate.get(Calendar.HOUR_OF_DAY)) {
//备份数据库
new DbBackups(getApplication()).execute("backupDatabase");
//更新数据库备份时间
SharedPreferencesUtil.saveData(getApplication(), "DbBackupTime", CommFunc.convertDa teToString(CommFunc.CONVERT_PATTERN_DATETIME, new Date()));
}
}
};
timer.schedule(timerTask, delay, period);//执行时间(每天的18点), 在执行的间隔时间(24小时)
} catch (Exception e) {
}
}
});
DbBackupsThread.start(); //启动线程
讲解:我是做了一个新的线程,只要程序运行起来了就去做定时任务,备份时间为每天的18点,可以通过重启线程修改全局变量来自定义备份时间,首先判断昨天是否备份过没有,如果没有就立即备份,然后进行正常的备份工作,如果线程启动时间是18点之前,就等待时间到18点进行备份,如果超过18点就立即备份,然后计算下次备份的时间差,然后等候下次备份,缺点是程序要是关了备份就无效了。还有一个坑就是安卓机制坑,取时间的时候会有8个小时的时间差,这点很重要,需要计算进去才能准确操作。