main
parent
b14cb65b70
commit
239a876094
@ -0,0 +1,289 @@
|
||||
package net.micode.notes.tool;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentProviderResult;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.database.Cursor;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import net.micode.notes.data.Notes;
|
||||
import net.micode.notes.data.Notes.CallNote;
|
||||
import net.micode.notes.data.Notes.NoteColumns;
|
||||
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
// 数据工具类,提供各种与笔记数据处理相关的方法
|
||||
public class DataUtils {
|
||||
public static final String TAG = "DataUtils";
|
||||
|
||||
// 批量删除笔记的方法
|
||||
public static boolean batchDeleteNotes(ContentResolver resolver, HashSet<Long> ids) {
|
||||
if (ids == null) {
|
||||
Log.d(TAG, "the ids is null");
|
||||
return true;
|
||||
}
|
||||
if (ids.size() == 0) {
|
||||
Log.d(TAG, "no id is in the hashset");
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
|
||||
for (long id : ids) {
|
||||
// 不允许删除系统根文件夹
|
||||
if (id == Notes.ID_ROOT_FOLDER) {
|
||||
Log.e(TAG, "Don't delete system folder root");
|
||||
continue;
|
||||
}
|
||||
// 创建删除操作的构建器
|
||||
ContentProviderOperation.Builder builder = ContentProviderOperation
|
||||
.newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
|
||||
operationList.add(builder.build());
|
||||
}
|
||||
|
||||
try {
|
||||
// 执行批量操作
|
||||
ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
|
||||
if (results == null || results.length == 0 || results[0] == null) {
|
||||
Log.d(TAG, "delete notes failed, ids:" + ids.toString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
|
||||
} catch (OperationApplicationException e) {
|
||||
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 将笔记移动到指定文件夹的方法
|
||||
public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(NoteColumns.PARENT_ID, desFolderId);
|
||||
values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId);
|
||||
values.put(NoteColumns.LOCAL_MODIFIED, 1);
|
||||
// 更新笔记的父文件夹ID等信息
|
||||
resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null);
|
||||
}
|
||||
|
||||
// 批量将笔记移动到指定文件夹的方法
|
||||
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet<Long> ids,
|
||||
long folderId) {
|
||||
if (ids == null) {
|
||||
Log.d(TAG, "the ids is null");
|
||||
return true;
|
||||
}
|
||||
|
||||
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
|
||||
for (long id : ids) {
|
||||
// 创建更新操作的构建器
|
||||
ContentProviderOperation.Builder builder = ContentProviderOperation
|
||||
.newUpdate(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
|
||||
builder.withValue(NoteColumns.PARENT_ID, folderId);
|
||||
builder.withValue(NoteColumns.LOCAL_MODIFIED, 1);
|
||||
operationList.add(builder.build());
|
||||
}
|
||||
|
||||
try {
|
||||
// 执行批量操作
|
||||
ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
|
||||
if (results == null || results.length == 0 || results[0] == null) {
|
||||
Log.d(TAG, "delete notes failed, ids:" + ids.toString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
|
||||
} catch (OperationApplicationException e) {
|
||||
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取除系统文件夹外的所有文件夹数量的方法
|
||||
public static int getUserFolderCount(ContentResolver resolver) {
|
||||
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)},
|
||||
null);
|
||||
int count = 0;
|
||||
if (cursor!= null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
try {
|
||||
count = cursor.getInt(0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, "get folder count failed:" + e.toString());
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// 检查笔记是否在笔记数据库中可见(非回收站且类型匹配)的方法
|
||||
public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
|
||||
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
|
||||
null,
|
||||
NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER,
|
||||
new String[]{String.valueOf(type)},
|
||||
null);
|
||||
boolean exist = false;
|
||||
if (cursor!= null) {
|
||||
if (cursor.getCount() > 0) {
|
||||
exist = true;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
// 检查笔记是否存在于笔记数据库中的方法
|
||||
public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) {
|
||||
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
|
||||
null, null, null, null);
|
||||
boolean exist = false;
|
||||
if (cursor!= null) {
|
||||
if (cursor.getCount() > 0) {
|
||||
exist = true;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
// 检查数据是否存在于数据数据库中的方法
|
||||
public static boolean existInDataDatabase(ContentResolver resolver, long dataId) {
|
||||
Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId),
|
||||
null, null, null, null);
|
||||
boolean exist = false;
|
||||
if (cursor!= null) {
|
||||
if (cursor.getCount() > 0) {
|
||||
exist = true;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
// 检查文件夹名称是否可见(非回收站且名称唯一)的方法
|
||||
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);
|
||||
boolean exist = false;
|
||||
if (cursor!= null) {
|
||||
if (cursor.getCount() > 0) {
|
||||
exist = true;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
// 获取指定文件夹中笔记的小部件属性集合的方法
|
||||
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},
|
||||
NoteColumns.PARENT_ID + "=?",
|
||||
new String[]{String.valueOf(folderId)},
|
||||
null);
|
||||
HashSet<AppWidgetAttribute> set = null;
|
||||
if (c!= null) {
|
||||
if (c.moveToFirst()) {
|
||||
set = new HashSet<AppWidgetAttribute>();
|
||||
do {
|
||||
try {
|
||||
AppWidgetAttribute widget = new AppWidgetAttribute();
|
||||
widget.widgetId = c.getInt(0);
|
||||
widget.widgetType = c.getInt(1);
|
||||
set.add(widget);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
}
|
||||
} while (c.moveToNext());
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
// 根据笔记ID获取通话号码的方法
|
||||
public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) {
|
||||
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
|
||||
new String[]{CallNote.PHONE_NUMBER},
|
||||
CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?",
|
||||
new String[]{String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE},
|
||||
null);
|
||||
if (cursor!= null && cursor.moveToFirst()) {
|
||||
try {
|
||||
return cursor.getString(0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, "Get call number fails " + e.toString());
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 根据电话号码和通话日期获取笔记ID的方法
|
||||
public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) {
|
||||
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
|
||||
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},
|
||||
null);
|
||||
if (cursor!= null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
try {
|
||||
return cursor.getLong(0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
Log.e(TAG, "Get call note id fails " + e.toString());
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 根据笔记ID获取笔记片段的方法
|
||||
public static String getSnippetById(ContentResolver resolver, long noteId) {
|
||||
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
|
||||
new String[]{NoteColumns.SNIPPET},
|
||||
NoteColumns.ID + "=?",
|
||||
new String[]{String.valueOf(noteId)},
|
||||
null);
|
||||
if (cursor!= null) {
|
||||
String snippet = "";
|
||||
if (cursor.moveToFirst()) {
|
||||
snippet = cursor.getString(0);
|
||||
}
|
||||
cursor.close();
|
||||
return snippet;
|
||||
}
|
||||
throw new IllegalArgumentException("Note is not found with id: " + noteId);
|
||||
}
|
||||
|
||||
// 格式化笔记片段的方法,去除首尾空格和换行符
|
||||
public static String getFormattedSnippet(String snippet) {
|
||||
if (snippet!= null) {
|
||||
snippet = snippet.trim();
|
||||
int index = snippet.indexOf('\n');
|
||||
if (index!= -1) {
|
||||
snippet = snippet.substring(0, index);
|
||||
}
|
||||
}
|
||||
return snippet;
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package net.micode.notes.tool;
|
||||
|
||||
// 用于处理与GTask相关的字符串常量的工具类
|
||||
public class GTaskStringUtils {
|
||||
|
||||
// GTask JSON中动作ID的键
|
||||
public final static String GTASK_JSON_ACTION_ID = "action_id";
|
||||
// GTask JSON中动作列表的键
|
||||
public final static String GTASK_JSON_ACTION_LIST = "action_list";
|
||||
// GTask JSON中动作类型的键
|
||||
public final static String GTASK_JSON_ACTION_TYPE = "action_type";
|
||||
// GTask JSON中创建动作类型的值
|
||||
public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create";
|
||||
// GTask JSON中获取所有动作类型的值
|
||||
public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all";
|
||||
// GTask JSON中移动动作类型的值
|
||||
public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move";
|
||||
// GTask JSON中更新动作类型的值
|
||||
public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update";
|
||||
// GTask JSON中创建者ID的键
|
||||
public final static String GTASK_JSON_CREATOR_ID = "creator_id";
|
||||
// GTask JSON中子实体的键
|
||||
public final static String GTASK_JSON_CHILD_ENTITY = "child_entity";
|
||||
// GTask JSON中客户端版本的键
|
||||
public final static String GTASK_JSON_CLIENT_VERSION = "client_version";
|
||||
// GTask JSON中完成状态的键
|
||||
public final static String GTASK_JSON_COMPLETED = "completed";
|
||||
// GTask JSON中当前列表ID的键
|
||||
public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id";
|
||||
// GTask JSON中默认列表ID的键
|
||||
public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id";
|
||||
// GTask JSON中已删除状态的键
|
||||
public final static String GTASK_JSON_DELETED = "deleted";
|
||||
// GTask JSON中目标列表的键
|
||||
public final static String GTASK_JSON_DEST_LIST = "dest_list";
|
||||
// GTask JSON中目标父级的键
|
||||
public final static String GTASK_JSON_DEST_PARENT = "dest_parent";
|
||||
// GTask JSON中目标父级类型的键
|
||||
public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type";
|
||||
// GTask JSON中实体增量的键
|
||||
public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta";
|
||||
// GTask JSON中实体类型的键
|
||||
public final static String GTASK_JSON_ENTITY_TYPE = "entity_type";
|
||||
// GTask JSON中获取已删除项的键
|
||||
public final static String GTASK_JSON_GET_DELETED = "get_deleted";
|
||||
// GTask JSON中ID的键
|
||||
public final static String GTASK_JSON_ID = "id";
|
||||
// GTask JSON中索引的键
|
||||
public final static String GTASK_JSON_INDEX = "index";
|
||||
// GTask JSON中最后修改时间的键
|
||||
public final static String GTASK_JSON_LAST_MODIFIED = "last_modified";
|
||||
// GTask JSON中最新同步点的键
|
||||
public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point";
|
||||
// GTask JSON中列表ID的键
|
||||
public final static String GTASK_JSON_LIST_ID = "list_id";
|
||||
// GTask JSON中列表的键
|
||||
public final static String GTASK_JSON_LISTS = "lists";
|
||||
// GTask JSON中名称的键
|
||||
public final static String GTASK_JSON_NAME = "name";
|
||||
// GTask JSON中新ID的键
|
||||
public final static String GTASK_JSON_NEW_ID = "new_id";
|
||||
// GTask JSON中笔记的键
|
||||
public final static String GTASK_JSON_NOTES = "notes";
|
||||
// GTask JSON中父级ID的键
|
||||
public final static String GTASK_JSON_PARENT_ID = "parent_id";
|
||||
// GTask JSON中前一个兄弟ID的键
|
||||
public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id";
|
||||
// GTask JSON中结果的键
|
||||
public final static String GTASK_JSON_RESULTS = "results";
|
||||
// GTask JSON中源列表的键
|
||||
public final static String GTASK_JSON_SOURCE_LIST = "source_list";
|
||||
// GTask JSON中任务的键
|
||||
public final static String GTASK_JSON_TASKS = "tasks";
|
||||
// GTask JSON中类型的键
|
||||
public final static String GTASK_JSON_TYPE = "type";
|
||||
// GTask JSON中组类型的值
|
||||
public final static String GTASK_JSON_TYPE_GROUP = "GROUP";
|
||||
// GTask JSON中任务类型的值
|
||||
public final static String GTASK_JSON_TYPE_TASK = "TASK";
|
||||
// GTask JSON中用户的键
|
||||
public final static String GTASK_JSON_USER = "user";
|
||||
|
||||
// MIUI文件夹前缀
|
||||
public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]";
|
||||
// 默认文件夹名称
|
||||
public final static String FOLDER_DEFAULT = "Default";
|
||||
// 通话记录文件夹名称
|
||||
public final static String FOLDER_CALL_NOTE = "Call_Note";
|
||||
// 元数据文件夹名称
|
||||
public final static String FOLDER_META = "METADATA";
|
||||
// 元数据中GTask ID的头部信息
|
||||
public final static String META_HEAD_GTASK_ID = "meta_gid";
|
||||
// 元数据中笔记的头部信息
|
||||
public final static String META_HEAD_NOTE = "meta_note";
|
||||
// 元数据中数据的头部信息
|
||||
public final static String META_HEAD_DATA = "meta_data";
|
||||
// 元数据笔记的名称(包含提示信息)
|
||||
public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE";
|
||||
}
|
Loading…
Reference in new issue