Compare commits

...

1 Commits
master ... dev

Author SHA1 Message Date
李嘉豪 6d2e7dd098 ljh
3 years ago

@ -14,34 +14,45 @@
*
*/
//包名
package net.micode.notes.tool;
//包的调用
/**
* Context
*
*
* 访广
*/
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;
//java自己的文件操作类
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";
// Singleton stuff
private static BackupUtils sInstance; //类里面为什么可以定义自身类的对象?
private static final String TAG = "BackupUtils";
//实例化一个BackupUtiles对象
private static BackupUtils sInstance;
//同步线程锁,其他试图访问该方法的线程将受到阻塞
public static synchronized BackupUtils getInstance(Context context) {
//ynchronized 关键字,代表这个方法加锁,相当于不管哪一个线程例如线程A
//Synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程例如线程A
//运行到这个方法时,都要检查有没有其它线程B或者C、 D等正在用这个方法(或者该类的其他同步方法)有的话要等正在使用synchronized方法的线程B或者C 、D运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。
//它包括两种用法synchronized 方法和 synchronized 块。
if (sInstance == null) {
@ -52,65 +63,103 @@ public class BackupUtils {
}
/**
* Following states are signs to represents backup or restore
* status
*
*/
// Currently, the sdcard is not mounted SD卡没有被装入手机
// 代表SD卡没有被装入手机
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;
// Backup or restore success 成功存储
// 成功存储
public static final int STATE_SUCCESS = 4;
//实例化一个TextExport的对象mTextExport
private TextExport mTextExport;
private BackupUtils(Context context) { //初始化函数
/**
* mTextExport
* @param context
*/
private BackupUtils(Context context) {
//初始化函数
mTextExport = new TextExport(context);
}
private static boolean externalStorageAvailable() { //外部存储功能是否可用
/**
* boolean
* @return boolean
*/
private static boolean externalStorageAvailable() {
//外部存储功能是否可用
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
/**
*
* @return
*/
public int exportToText() {
return mTextExport.exportToText();
}
/**
*
* @return
*/
public String getExportedTextFileName() {
return mTextExport.mFileName;
}
/**
*
* @return
*/
public String getExportedTextFileDir() {
return mTextExport.mFileDirectory;
}
/**
* ID
*
*/
private static class TextExport {
/**
* Note
* NoteID
* Note
* Note
* Note
*/
private static final String[] NOTE_PROJECTION = {
NoteColumns.ID,
NoteColumns.MODIFIED_DATE,
NoteColumns.SNIPPET,
NoteColumns.TYPE
};
//定义了一个数组储存的是数据的信息
private static final int NOTE_COLUMN_ID = 0;
//初始化变迁修改时间状态
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,
};
/**
*01访24
*/
private static final int DATA_COLUMN_CONTENT = 0;
private static final int DATA_COLUMN_MIME_TYPE = 1;
@ -118,16 +167,24 @@ public class BackupUtils {
private static final int DATA_COLUMN_CALL_DATE = 2;
private static final int DATA_COLUMN_PHONE_NUMBER = 4;
/**
* =>0;=>1;=>2
*/
private final String [] TEXT_FORMAT;
private static final int FORMAT_FOLDER_NAME = 0;
private static final int FORMAT_NOTE_DATE = 1;
private static final int FORMAT_NOTE_CONTENT = 2;
//为该类定义一个私有的上下文类
private Context mContext;
//文件名
private String mFileName;
//文件路径
private String mFileDirectory;
/**
*
* @param context
*/
public TextExport(Context context) {
TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note);
mContext = context;
@ -135,15 +192,22 @@ public class BackupUtils {
mFileDirectory = "";
}
/**
* ID
* @param id
* @return
*/
private String getFormat(int id) { //获取文本的组成部分
return TEXT_FORMAT[id];
}
/**
* Export the folder identified by folder id to text
* parent ididnoteIDNote
* @param folderId
* @param ps
*/
private void exportFolderToText(String folderId, PrintStream ps) {
// Query notes belong to this folder 通过查询parent id是文件夹id的note来选出制定ID文件夹下的Note
//通过查询parent id是文件夹id的note来选出制定ID文件夹下的Note
Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI,
NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[] {
folderId
@ -152,7 +216,7 @@ public class BackupUtils {
if (notesCursor != null) {
if (notesCursor.moveToFirst()) {
do {
// Print note's last modified date ps里面保存有这份note的日期
// ps里面保存有这份note的日期
ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format(
mContext.getString(R.string.format_datetime_mdhm),
notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE))));
@ -166,49 +230,61 @@ public class BackupUtils {
}
/**
* Export note identified by id to a print stream
* 便
* @param noteId
* @param ps
*/
private void exportNoteToText(String noteId, PrintStream ps) {
//利用光标来扫描内容区别为callnote和note两种靠ps.printline输出
Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI,
DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] {
noteId
}, null);
if (dataCursor != null) { //利用光标来扫描内容区别为callnote和note两种靠ps.printline输出
//如果游标不空
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)) { //判断是否为空字符
//判断是否为空字符
if (!TextUtils.isEmpty(phoneNumber)) {
//输出电话号码phoneNumber
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
phoneNumber));
}
// Print call date
// 输出 call date
ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat
.format(mContext.getString(R.string.format_datetime_mdhm),
callDate)));
// Print call attachment location
// 输出位置location
if (!TextUtils.isEmpty(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
// 在note下面输出一条线
try {
ps.write(new byte[] {
Character.LINE_SEPARATOR, Character.LETTER_NUMBER

@ -34,9 +34,31 @@ import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import java.util.ArrayList;
import java.util.HashSet;
/**
*
*/
public class DataUtils {
public static final String TAG = "DataUtils";
/**
* 便
*
* @param resolver
* @param ids
* @return
*/
public static boolean batchDeleteNotes(ContentResolver resolver, HashSet<Long> ids) { //直接删除多个笔记
/*1. Android Logcat使便
Log.v vverbose使Log.v(,);
Log.ddebugDDMSLogcat
Log.i绿informationLog.vLog.diwe
Log.wwarningAndroidLog.e
Log.eerror*/
if (ids == null) {
Log.d(TAG, "the ids is null");
return true;
@ -48,7 +70,7 @@ public class DataUtils {
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>(); //提供一个任务列表
for (long id : ids) {
if(id == Notes.ID_ROOT_FOLDER) {
if (id == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Don't delete system folder root");
continue;
} //如果发现是根文件夹,则不删除
@ -72,6 +94,13 @@ public class DataUtils {
return false;
}
/**
*
* @param resolver
* @param id
* @param srcFolderId
* @param desFolderId
*/
public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) {
ContentValues values = new ContentValues();
values.put(NoteColumns.PARENT_ID, desFolderId);
@ -80,6 +109,13 @@ public class DataUtils {
resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null); //对需要移动的便签进行数据更新然后用update实现
}
/**
*
* @param resolver
* @param ids
* @param folderId
* @return
*/
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet<Long> ids,
long folderId) {
if (ids == null) {
@ -112,18 +148,24 @@ public class DataUtils {
}
/**
*
* Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}}
*/
/**
*
* @param resolver
* @return num
*/
public static int getUserFolderCount(ContentResolver resolver) {
Cursor cursor =resolver.query(Notes.CONTENT_NOTE_URI,
new String[] { "COUNT(*)" },
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
new String[]{"COUNT(*)"},
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?",
new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)},
new String[]{String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)},
null); //筛选条件源文件不为trash folder
int count = 0;
if(cursor != null) {
if(cursor.moveToFirst()) {
if (cursor != null) {
if (cursor.moveToFirst()) {
try {
count = cursor.getInt(0);
} catch (IndexOutOfBoundsException e) {
@ -136,11 +178,17 @@ public class DataUtils {
return count;
}
/**
*
* @param resolver
* @param noteId
* @param type
*/
public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), //通过withAppendedId方法为该Uri加上ID
null,
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER,
new String [] {String.valueOf(type)},
new String[]{String.valueOf(type)},
null); //查询条件type符合且不属于垃圾文件夹
boolean exist = false;
@ -153,6 +201,12 @@ public class DataUtils {
return exist;
}
/**
*
* @param resolver
* @param noteId
* @return
*/
public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) {
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
null, null, null, null);
@ -167,6 +221,12 @@ public class DataUtils {
return exist;
}
/**
*
* @param resolver
* @param dataId
* @return
*/
public static boolean existInDataDatabase(ContentResolver resolver, long dataId) {
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId),
null, null, null, null);
@ -181,16 +241,22 @@ public class DataUtils {
return exist;
}
/**
*
* @param resolver
* @param name
* @return
*/
public static boolean checkVisibleFolderName(ContentResolver resolver, String name) {
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null,
NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER +
" AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER +
" AND " + NoteColumns.SNIPPET + "=?",
new String[] { name }, null);
new String[]{name}, null);
//通过名字查询文件是否存在
boolean exist = false;
if(cursor != null) {
if(cursor.getCount() > 0) {
if (cursor != null) {
if (cursor.getCount() > 0) {
exist = true;
}
cursor.close();
@ -198,11 +264,17 @@ public class DataUtils {
return exist;
}
/**
* 使hashsetidtype
* @param resolver
* @param folderId
* @return
*/
public static HashSet<AppWidgetAttribute> getFolderNoteWidget(ContentResolver resolver, long folderId) {
Cursor c = resolver.query(Notes.CONTENT_NOTE_URI,
new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE },
new String[]{NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE},
NoteColumns.PARENT_ID + "=?",
new String[] { String.valueOf(folderId) },
new String[]{String.valueOf(folderId)},
null); //查询条件父ID是传入的folderId;
HashSet<AppWidgetAttribute> set = null;
@ -225,11 +297,17 @@ public class DataUtils {
return set;
}
/**
* ID
* @param resolver
* @param noteId
* @return
*/
public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) {
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.PHONE_NUMBER },
new String[]{CallNote.PHONE_NUMBER},
CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?",
new String [] { String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE },
new String[]{String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE},
null);
if (cursor != null && cursor.moveToFirst()) {
@ -244,12 +322,19 @@ public class DataUtils {
return "";
}
/**
* ID
* @param resolver
* @param phoneNumber
* @param callDate
* @return
*/
public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) {
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.NOTE_ID },
new String[]{CallNote.NOTE_ID},
CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL("
+ CallNote.PHONE_NUMBER + ",?)",
new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber },
new String[]{String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber},
null);
//通过数据库操作查询条件是callDate和phoneNumber匹配传入参数的值
@ -266,11 +351,17 @@ public class DataUtils {
return 0;
}
/**
* note
* @param resolver
* @param noteId
* @return
*/
public static String getSnippetById(ContentResolver resolver, long noteId) {
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
new String [] { NoteColumns.SNIPPET },
new String[]{NoteColumns.SNIPPET},
NoteColumns.ID + "=?",
new String [] { String.valueOf(noteId)},
new String[]{String.valueOf(noteId)},
null);//查询条件noteId
if (cursor != null) {
@ -283,6 +374,12 @@ public class DataUtils {
}
throw new IllegalArgumentException("Note is not found with id: " + noteId);
}
/**
*
* @param snippet
* @return
*/
public static String getFormattedSnippet(String snippet) { //对字符串进行格式处理,将字符串两头的空格去掉,同时将换行符去掉
if (snippet != null) {
snippet = snippet.trim();

@ -16,7 +16,10 @@
//简介定义了很多的静态字符串目的就是为了提供jsonObject中相应字符串的"key"。把这些静态的定义单独写到了一个类里面,这是非常好的编程规范
package net.micode.notes.tool;
//这个类就是定义了一堆static string实际就是为jsonObject提供Key把这些定义全部写到一个类里方便查看管理是一个非常好的编程习惯
/**
* static stringjsonObjectKey
* 便
*/
public class GTaskStringUtils {
public final static String GTASK_JSON_ACTION_ID = "action_id";

@ -79,7 +79,8 @@ public class ResourceParser {
return BG_EDIT_TITLE_RESOURCES[id];
}
}
//直接获取默认的背景颜色。看不太懂这个PREFERENCE_SET_BG_COLOR_KEY是个final string,也就是说getBoolean肯定执行else为什么要这么写
//直接获取默认的背景颜色。看不太懂这个PREFERENCE_SET_BG_COLOR_KEY是个final string,
// 也就是说getBoolean肯定执行else为什么要这么写
public static int getDefaultBgId(Context context) {
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) {

Loading…
Cancel
Save