package com.maxiee.heartbeat.backup;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import com.maxiee.heartbeat.R;
import com.maxiee.heartbeat.common.FileUtils;
import com.maxiee.heartbeat.database.tables.ImageTable;
import com.maxiee.heartbeat.database.tables.ThoughtResTable;
import com.maxiee.heartbeat.database.utils.DatabaseUtils;
import com.maxiee.heartbeat.database.utils.ImageUtils;
import com.maxiee.heartbeat.database.utils.ThoughtUtils;
import com.maxiee.heartbeat.model.Image;
import com.maxiee.heartbeat.model.ThoughtRes;
import com.maxiee.heartbeat.model.Thoughts;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Created by maxiee on 15-8-10.
*/
public class BackupManager {
public static final String TAG = BackupManager.class.getSimpleName();
private final static String DB = "heartbeat";
private final static String BACKUP_PATH = "HeartBeat";
private final static String BACKUP_PREFIX = "[Backup]";
private static final int BUFFER_SIZE = 2048;
public static String backupSD(Context context) {
try {
File curDb = context.getDatabasePath(DB);
File bakFile = FileUtils.generateBackupFile(context);
FileDES.doEncryptFile(curDb, bakFile);
return bakFile.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String backupCloud(Context context) {
String path = backupSD(context);
if (path == null) return context.getString(R.string.backup_failed);
Uri db = Uri.fromFile(new File(path));
Intent i = new Intent();
i.setAction(Intent.ACTION_SEND);
i.setType("*/*");
i.putExtra(Intent.EXTRA_STREAM, db);
if (i.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(i);
} else {
return context.getString(R.string.share_not_found);
}
return null;
}
public static String restore(Context context, Intent data) {
try {
File curDB = context.getDatabasePath(DB);
OutputStream out = new FileOutputStream(curDB);
InputStream in = context.getContentResolver().openInputStream(data.getData());
// 使用解密
if (!FileDES.doDecryptFile(in, out)) {
return context.getString(R.string.restore_failed);
}
in.close();
out.close();
return context.getString(R.string.restore_ok);
} catch (Exception e) {
e.printStackTrace();
return context.getString(R.string.restore_failed);
}
}
public static String backupAll(Context context) {
String dbPath = backupSD(context);
if (dbPath == null) return null;
try {
File zipFile = FileUtils.generateBackupAllZip(context);
FileOutputStream dest = new FileOutputStream(zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER_SIZE];
File f = FileUtils.getImageDir();
ArrayList<File> files = new ArrayList<>(Arrays.asList(f.listFiles()));
files.add(new File(dbPath));
for (File file : files) {
FileInputStream fi = new FileInputStream(file);
BufferedInputStream origin = new BufferedInputStream(fi, BUFFER_SIZE);
ZipEntry entry = new ZipEntry(file.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(data,0, BUFFER_SIZE)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
return zipFile.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String restoreAll(Context context, Intent data) {
String path = data.getData().getPath();
if (!path.contains(FileUtils.BACKUP_ZIP_PREFIX)) return context.getString(R.string.restore_failed);
try {
InputStream is = context.getContentResolver().openInputStream(data.getData());
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
int count;
byte d[] = new byte[BUFFER_SIZE];
String entryName = entry.getName();
int entryType = FileUtils.detectFileType(entryName);
if (entryType == FileUtils.FILE_TYPE_DB) {
File curDB = context.getDatabasePath(DB);
OutputStream out = new FileOutputStream(curDB);
// 使用解密
FileDES.doDecryptFileNotClose(zis, out);
out.close();
}
else if (entryType == FileUtils.FILE_TYPE_IMAGE) {
OutputStream out = new FileOutputStream(new File(FileUtils.getImageDir(), entryName));
BufferedOutputStream dest = new BufferedOutputStream(out, BUFFER_SIZE);
while ((count = zis.read(d, 0, BUFFER_SIZE)) != -1) {
dest.write(d, 0, count);
}
dest.flush();
dest.close();
}
}
zis.close();
return context.getString(R.string.restore_ok);
} catch (Exception e) {
e.printStackTrace();
}
return context.getString(R.string.restore_failed);
}
public static boolean needTransGallery(Context context) {
boolean ret = false;
Cursor eventImage = DatabaseUtils.query(
context, ImageTable.NAME,
new String[] {ImageTable.ID, ImageTable.URI},
ImageTable.URI + " like ?", new String[] {"%/%"});
Log.d(TAG, String.format("事件图片有%d需要迁移.", eventImage.getCount()));
if (eventImage.getCount() > 1) ret = true;
eventImage.close();
if (ret) return true;
Cursor thoughtImage = DatabaseUtils.query(
context, ThoughtResTable.NAME,
new String[] {ThoughtResTable.ID, ThoughtResTable.TYPE,
ThoughtResTable.PATH, ThoughtResTable.THOUGHT_ID},
ThoughtResTable.PATH + " like ?", new String[] {"%/%"});
Log.d(TAG, String.format("感想图片有%d需要迁移.", thoughtImage.getCount()));
if (thoughtImage.getCount() > 1) ret = true;
thoughtImage.close();
return ret;
}
public static void transGallery(Context context) {
Cursor eventImage = DatabaseUtils.query(
context, ImageTable.NAME,
new String[] {ImageTable.ID, ImageTable.URI},
ImageTable.URI + " like ?", new String[] {"%/%"});
Log.d(TAG, String.format("事件图片有%d需要迁移.", eventImage.getCount()));
int transCount = 0;
if (eventImage.getCount() > 1) {
while (eventImage.moveToNext()) {
Image i = ImageUtils.queryImage(eventImage);
try {
String filename = FileUtils.copyImageToHeartBeat(i.getPath());
ImageUtils.updateImageByImageId(context, i.getId(), filename);
transCount++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
Log.d(TAG, String.format("成功迁移%d幅图片至心动目录.", transCount));
eventImage.close();
transCount = 0;
Cursor thoughtImage = DatabaseUtils.query(
context, ThoughtResTable.NAME,
new String[] {ThoughtResTable.ID, ThoughtResTable.TYPE,
ThoughtResTable.PATH, ThoughtResTable.THOUGHT_ID},
ThoughtResTable.PATH + " like ?", new String[] {"%/%"});
Log.d(TAG, String.format("感想图片有%d需要迁移.", thoughtImage.getCount()));
if (thoughtImage.getCount() > 1) {
while (thoughtImage.moveToNext()) {
ThoughtRes r = ThoughtUtils.queryThoughtRes(thoughtImage);
if (r.getResType() != Thoughts.Thought.RES_IMAGE) continue;
try {
String filename = FileUtils.copyImageToHeartBeat(r.getPath());
ThoughtUtils.updateRes(context, r.getThoughtId(), r.getResType(), filename);
transCount++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
Log.d(TAG, String.format("成功迁移%d幅图片至心动目录.", transCount));
thoughtImage.close();
}
}