diff --git a/src/mi_note/app/src/main/java/net/micode/notes/data/Notes.java b/src/mi_note/app/src/main/java/net/micode/notes/data/Notes.java index 0ffdf43..3d22f10 100644 --- a/src/mi_note/app/src/main/java/net/micode/notes/data/Notes.java +++ b/src/mi_note/app/src/main/java/net/micode/notes/data/Notes.java @@ -31,7 +31,7 @@ public class Notes { public static final int TYPE_NOTE = 0; // 文件夹标识 public static final int TYPE_FOLDER = 1; - // 系统标识 + // 系统文件夹标识 public static final int TYPE_SYSTEM = 2; /** diff --git a/src/mi_note/app/src/main/java/net/micode/notes/tool/DataUtils.java b/src/mi_note/app/src/main/java/net/micode/notes/tool/DataUtils.java index 28a7a9e..4825109 100644 --- a/src/mi_note/app/src/main/java/net/micode/notes/tool/DataUtils.java +++ b/src/mi_note/app/src/main/java/net/micode/notes/tool/DataUtils.java @@ -29,6 +29,7 @@ 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.data.NotesDatabaseHelper; import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; import java.util.ArrayList; @@ -38,7 +39,7 @@ import java.util.HashSet; * @author hzx * 版本:1.0 * 创建日期:2023/10/29 - * 描述:DataUtils 数据处理工具类 + * 描述:DataUtils 便签、文件夹、便签内容等数据处理工具类 */ public class DataUtils { public static final String TAG = "DataUtils"; @@ -92,14 +93,31 @@ public class DataUtils { return false; } + /** + * 将一个便签从原文件夹移动到另一个文件夹里 + * @param resolver 内容解析器 + * @param id 便签ID + * @param srcFolderId 原文件夹ID + * @param desFolderId 目标文件夹ID + */ public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) { ContentValues values = new ContentValues(); + // 将便签的父ID改为目标文件夹ID values.put(NoteColumns.PARENT_ID, desFolderId); + // 将便签的原父ID改为移动前的文件夹ID values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId); values.put(NoteColumns.LOCAL_MODIFIED, 1); + // 将便签ID放入uri中然后通过内容解析器执行更新操作 resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null); } + /** + * 批量移动便签到指定文件夹里 + * @param resolver 内容解析器 + * @param ids 便签ID集合 + * @param folderId 目标文件夹ID + * @return 是否成功 + */ public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, long folderId) { if (ids == null) { @@ -107,34 +125,43 @@ public class DataUtils { return true; } + // 创建一个内容提供者操作列表 ArrayList operationList = new ArrayList(); 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()); + // 更新失败,没有行影响 + Log.d(TAG, "update 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; } /** - * Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}} + * 获取除系统文件夹{@link Notes#TYPE_SYSTEM}(根文件夹、垃圾文件夹、临时文件夹)外的文件夹数量 + * @param resolver 内容解析器 + * @return int 普通文件夹数量 */ public static int getUserFolderCount(ContentResolver resolver) { + // 查询不在垃圾文件夹(回收站)中的普通文件夹数量 Cursor cursor =resolver.query(Notes.CONTENT_NOTE_URI, new String[] { "COUNT(*)" }, NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?", @@ -145,6 +172,7 @@ public class DataUtils { if(cursor != null) { if(cursor.moveToFirst()) { try { + // 获取查询结果 count = cursor.getInt(0); } catch (IndexOutOfBoundsException e) { Log.e(TAG, "get folder count failed:" + e.toString()); @@ -156,7 +184,15 @@ public class DataUtils { return count; } + /** + * 判断指定ID和类型的文件(便签或文件夹)是否在数据库可见 存在于数据库,且不在回收站中 + * @param resolver 内容解析器 + * @param noteId 文件ID + * @param type 文件类型 {@link NoteColumns#TYPE} 便签或文件夹 + * @return true or false + */ public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) { + // 通过resolver查询 Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null, NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER, @@ -166,6 +202,7 @@ public class DataUtils { boolean exist = false; if (cursor != null) { if (cursor.getCount() > 0) { + // 有查询结果,说明指定便签在数据库可见 exist = true; } cursor.close(); @@ -173,13 +210,21 @@ public class DataUtils { return exist; } + /** + * 判断指定便签ID的便签是否存在于数据库中 + * @param resolver 内容解析器 + * @param noteId 便签ID + * @return true or false + */ 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(); @@ -187,13 +232,21 @@ public class DataUtils { return exist; } + /** + * 判断指定ID的数据记录{@link NotesDatabaseHelper.TABLE#DATA}是否存在于数据库中 + * @param resolver 内容解析器 + * @param dataId 数据项ID + * @return true or false + */ 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(); @@ -201,7 +254,14 @@ public class DataUtils { return exist; } + /** + * 检查指定名字的文件夹是否在数据库可见 存在于数据库且不在回收站中 + * @param resolver 内容解析器 + * @param name 文件夹名 + * @return true or false + */ 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 + @@ -210,6 +270,7 @@ public class DataUtils { boolean exist = false; if(cursor != null) { if(cursor.getCount() > 0) { + // 查询有结果 exist = true; } cursor.close(); @@ -217,7 +278,14 @@ public class DataUtils { return exist; } + /** + * 获取指定ID的文件夹的便签小部件 + * @param resolver 内容解析器 + * @param folderId 文件夹ID + * @return HashSet 小部件属性集合 + */ public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) { + // 查询小部件ID和类型 Cursor c = resolver.query(Notes.CONTENT_NOTE_URI, new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE }, NoteColumns.PARENT_ID + "=?", @@ -228,11 +296,13 @@ public class DataUtils { if (c != null) { if (c.moveToFirst()) { set = new HashSet(); + // 遍历查询到的所有小部件 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()); @@ -244,7 +314,14 @@ public class DataUtils { return set; } + /** + * 通过便签ID获取通话号码 + * @param resolver 内容解析器 + * @param noteId 便签ID + * @return 电话号码 + */ 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 + "=?", @@ -253,6 +330,7 @@ public class DataUtils { if (cursor != null && cursor.moveToFirst()) { try { + // 返回查询到的电话号码 return cursor.getString(0); } catch (IndexOutOfBoundsException e) { Log.e(TAG, "Get call number fails " + e.toString()); @@ -263,7 +341,15 @@ public class DataUtils { return ""; } + /** + * 通过电话号码和通话日期获取便签ID + * @param resolver 内容解析器 + * @param phoneNumber 电话号码 + * @param callDate 通话日期 + * @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(" @@ -274,6 +360,7 @@ public class DataUtils { if (cursor != null) { if (cursor.moveToFirst()) { try { + // 返回查询到的便签ID return cursor.getLong(0); } catch (IndexOutOfBoundsException e) { Log.e(TAG, "Get call note id fails " + e.toString()); @@ -284,7 +371,14 @@ public class DataUtils { return 0; } + /** + * 通过文件ID查询文件夹名或便签文本内容 + * @param resolver 内容解析器 + * @param noteId 文件ID + * @return 文件夹名称或便签文本内容 + */ public static String getSnippetById(ContentResolver resolver, long noteId) { + // 通过内容解析器查询 Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, new String [] { NoteColumns.SNIPPET }, NoteColumns.ID + "=?", @@ -294,19 +388,28 @@ public class DataUtils { 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); } + /** + * 获取格式化后的snippet 去掉首尾的空白字符(换行符、空格等) + * 如果还有换行符,则截取第一个换行符之前的内容 + * @param snippet 文件夹名或便签文本内容 + * @return 格式化后的结果 + */ 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); } }