You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
git-xiaomibianqian/src/tool/BackupUtils.java

343 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) 打开网站的操作
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.tool;//定义小米便签 功能类
import android.content.Context;//导入各种需要的类
import android.database.Cursor;//查询数据类型
import android.os.Environment;//导入安卓环境包
import android.text.TextUtils;//导入安卓文本功能包
import android.text.format.DateFormat;//用于转化日期格式
import android.util.Log;//打印与查看日志
import net.micode.notes.R;//从项目的其他软件包中调用类
import net.micode.notes.data.Notes;//数据便签类
import net.micode.notes.data.Notes.DataColumns;//数据类型类
import net.micode.notes.data.Notes.DataConstants;//常数类
import net.micode.notes.data.Notes.NoteColumns;//便签类
import java.io.File;//引入文件操作类
import java.io.FileNotFoundException;//文件未找到的错误处理
import java.io.FileOutputStream;//文件的输入
import java.io.IOException;//操作错误处理
import java.io.PrintStream;//导入需要的包
public class BackupUtils {//此处为备份工具包
private static final String TAG = "BackupUtils";//实化一个BackupUtils的对象
// Singleton stuff
private static BackupUtils sInstance;//初始化sInstance
public static synchronized BackupUtils getInstance(Context context) {//如果当前备份不在,则再新声明一个
if (sInstance == null) {
sInstance = new BackupUtils(context);
}
return sInstance;//返回当前的sInstance值
}
/**
* Following states are signs to represents backup or restore
* status
*/
// Currently, the sdcard is not mounted
public static final int STATE_SD_CARD_UNMOUONTED = 0;//备份文件夹不存在
// The backup file not exist
public static final int STATE_BACKUP_FILE_NOT_EXIST = 1;//变量表示备份的文件不存在
// The data is not well formated, may be changed by other programs
public static final int STATE_DATA_DESTROIED = 2;//超时异常
// Some run-time exception which causes restore or backup fails
public static final int STATE_SYSTEM_ERROR = 3;//系统错误状态为3
// Backup or restore success
public static final int STATE_SUCCESS = 4;//变量表示备份成功
private TextExport mTextExport;//实例化一个为mTextExport的对象
private BackupUtils(Context context) {//初始化构造函数
mTextExport = new TextExport(context);
}
private static boolean externalStorageAvailable() {//判断外部存储设备是否有效
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
public int exportToText() {//输出至文本
return mTextExport.exportToText();
}
public String getExportedTextFileName() {//返回获取的文件名
return mTextExport.mFileName;
}
public String getExportedTextFileDir() {//返回文件的目录
return mTextExport.mFileDirectory;
}
private static class TextExport {//内部类:文本输出
private static final String[] NOTE_PROJECTION = {//定义了一个数组存储便签的信息
NoteColumns.ID,//ID
NoteColumns.MODIFIED_DATE,//日期
NoteColumns.SNIPPET,
NoteColumns.TYPE
};
private static final int NOTE_COLUMN_ID = 0;//初始化便签ID
private static final int NOTE_COLUMN_MODIFIED_DATE = 1;//初始化修改时间
private static final int NOTE_COLUMN_SNIPPET = 2;//初始化小段消息状态
private static final String[] DATA_PROJECTION = {//定义字符串存储函数的基本信息
DataColumns.CONTENT,
DataColumns.MIME_TYPE,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
private static final int DATA_COLUMN_CONTENT = 0;//表示设定数据内容表示为0
private static final int DATA_COLUMN_MIME_TYPE = 1;//数据媒体类型标识为1
private static final int DATA_COLUMN_CALL_DATE = 2;//访问日期表示为2
private static final int DATA_COLUMN_PHONE_NUMBER = 4;//电话号码表示为4
private final String [] TEXT_FORMAT;//文档格式标识
private static final int FORMAT_FOLDER_NAME = 0;//文件命名格式表示为0
private static final int FORMAT_NOTE_DATE = 1;//便签日期格式表示为1
private static final int FORMAT_NOTE_CONTENT = 2;//便签目录格式
private Context mContext;//定义上下文类
private String mFileName;//定义文件名
private String mFileDirectory;//文件路径
public TextExport(Context context) {//从context类实例中花去信息给对应的属性赋初始值
TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note);
mContext = context;
mFileName = "";
mFileDirectory = "";
}
private String getFormat(int id) {
return TEXT_FORMAT[id];
}//获取文本组成部分
/**
* Export the folder identified by folder id to text
*/
private void exportFolderToText(String folderId, PrintStream ps) {//通过文件夹目录ID将目录导出后成为文件
// Query notes belong to this folder
Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI,
NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[] {
folderId
}, null);
if (notesCursor != null) {
if (notesCursor.moveToFirst()) {
do {
// Print note's last modified date
ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format(
mContext.getString(R.string.format_datetime_mdhm),
notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE))));
// Query data belong to this note
String noteId = notesCursor.getString(NOTE_COLUMN_ID);
exportNoteToText(noteId, ps);
} while (notesCursor.moveToNext());
}
notesCursor.close();//关闭游标
}
}
/**
* Export note identified by id to a print stream
*/
private void exportNoteToText(String noteId, PrintStream ps) {//函数:将便签的内容以文本的形式显示在屏幕上
Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI,//利用光标来扫描内容
DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] {
noteId
}, null);
if (dataCursor != null) {//如果光标不为空
if (dataCursor.moveToFirst()) {//游标已经在第一步就位
do {
String mimeType = dataCursor.getString(DATA_COLUMN_MIME_TYPE);//获取便签媒体类型
if (DataConstants.CALL_NOTE.equals(mimeType)) {//判断便签的内容
// Print phone number
String phoneNumber = dataCursor.getString(DATA_COLUMN_PHONE_NUMBER);//获取电话号码
long callDate = dataCursor.getLong(DATA_COLUMN_CALL_DATE);//获取通话时间
String location = dataCursor.getString(DATA_COLUMN_CONTENT);//获取地址
if (!TextUtils.isEmpty(phoneNumber)) {//判断是否为空字符
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
phoneNumber));
}
// Print call date
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat//输出电话号码
.format(mContext.getString(R.string.format_datetime_mdhm),
callDate)));
// Print call attachment location
if (!TextUtils.isEmpty(location)) {//输出位置location
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
location));
}
} else if (DataConstants.NOTE.equals(mimeType)) {//如果便签的内容存在,则直接输出
String content = dataCursor.getString(DATA_COLUMN_CONTENT);
if (!TextUtils.isEmpty(content)) {//如果便签内容不为空
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
content));
}
}
} while (dataCursor.moveToNext());//光标下移
}
dataCursor.close();//关闭光标
}
// print a line separator between note
try {//正常情况再note下面输出一条线
ps.write(new byte[] {
Character.LINE_SEPARATOR, Character.LETTER_NUMBER
});
} catch (IOException e) {//获取错误信息
Log.e(TAG, e.toString());
}
}
/**
* Note will be exported as text which is user readable
*/
public int exportToText() {//以TEXT形式输出到外部设备
if (!externalStorageAvailable()) {//如果外部设备未安装好,返回对应状态
Log.d(TAG, "Media was not mounted");
return STATE_SD_CARD_UNMOUONTED;
}
PrintStream ps = getExportToTextPrintStream();//获取存储信息
if (ps == null) {//如果没有得到正常的数据流,则输出错误信息
Log.e(TAG, "get print stream error");
return STATE_SYSTEM_ERROR;
}
// First export folder and its notes
Cursor folderCursor = mContext.getContentResolver().query(//定位需要导出的文件夹
Notes.CONTENT_NOTE_URI,
NOTE_PROJECTION,
"(" + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + " AND "
+ NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + ") OR "
+ NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER, null, null);
if (folderCursor != null) {//如果文件夹不为空,即存在文件夹
if (folderCursor.moveToFirst()) {//文件光标再第一行就位
do {
// Print folder's name
String folderName = "";
if(folderCursor.getLong(NOTE_COLUMN_ID) == Notes.ID_CALL_RECORD_FOLDER) {//找到文件名
folderName = mContext.getString(R.string.call_record_folder_name);
} else {
folderName = folderCursor.getString(NOTE_COLUMN_SNIPPET);//取便签为便签名字
}
if (!TextUtils.isEmpty(folderName)) {//判断folderName是否存在
ps.println(String.format(getFormat(FORMAT_FOLDER_NAME), folderName));
}
String folderId = folderCursor.getString(NOTE_COLUMN_ID);//通过便签ID获得folderID
exportFolderToText(folderId, ps);
} while (folderCursor.moveToNext());//文件夹的光标下移
}
folderCursor.close();//关闭光标
}
// Export notes in root's folder
Cursor noteCursor = mContext.getContentResolver().query(//输出根目录下面的笔记
Notes.CONTENT_NOTE_URI,
NOTE_PROJECTION,
NoteColumns.TYPE + "=" + +Notes.TYPE_NOTE + " AND " + NoteColumns.PARENT_ID
+ "=0", null, null);
if (noteCursor != null) {//如果笔记游标不为空
if (noteCursor.moveToFirst()) {//便签光标下移
do {
ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format(//输出修改日期
mContext.getString(R.string.format_datetime_mdhm),
noteCursor.getLong(NOTE_COLUMN_MODIFIED_DATE))));
// Query data belong to this note
String noteId = noteCursor.getString(NOTE_COLUMN_ID);//找到这块数据的ID
exportNoteToText(noteId, ps);
} while (noteCursor.moveToNext());//便签光标下移
}
noteCursor.close();//关闭游标
}
ps.close();
return STATE_SUCCESS; //返回成功导出状态
}
/**
* Get a print stream pointed to the file {@generateExportedTextFile}
*/
private PrintStream getExportToTextPrintStream() {//获取指向文件的打印流
File file = generateFileMountedOnSDcard(mContext, R.string.file_path,//创建文件
R.string.file_name_txt_format);
if (file == null) {//如果文件夹为空,则创建失败
Log.e(TAG, "create file to exported failed");
return null;
}
mFileName = file.getName();//得到文件名
mFileDirectory = mContext.getString(R.string.file_path);//获取文件路径
PrintStream ps = null;//初始化ps
try {//将ps输出流输出到特定的文件目的是导出文件
FileOutputStream fos = new FileOutputStream(file);
ps = new PrintStream(fos);
} catch (FileNotFoundException e) {//给出错误信息
e.printStackTrace();
return null;
} catch (NullPointerException e) {//捕获空指针异常
e.printStackTrace();
return null;
}
return ps;
}
}
/**
* Generate the text file to store imported data
*/
private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) {
//产生用于存储输入信息的文件
StringBuilder sb = new StringBuilder();//构建一个动态字符串将外部信息加入其中
sb.append(Environment.getExternalStorageDirectory());//加入路径
sb.append(context.getString(filePathResId));//文件的存储路径
File filedir = new File(sb.toString());//存储路径信息
sb.append(context.getString(//格式化输出当前系统时间
fileNameFormatResId,
DateFormat.format(context.getString(R.string.format_date_ymd),//将当前的系统时间以预定的格式输出
System.currentTimeMillis())));
File file = new File(sb.toString());//将输出连接到一个文件里
try {
if (!filedir.exists()) {//如果文件不存在,则重建
filedir.mkdir();
}
if (!file.exists()) {
file.createNewFile();
}
return file;//返回导出的文件
} catch (SecurityException e) {//处理碰到的异常
e.printStackTrace();
} catch (IOException e) {//捕获异常
e.printStackTrace();
}
return null;
}
}