diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Contact.java b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Contact.java index d97ac5d..a291d2a 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Contact.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Contact.java @@ -25,49 +25,79 @@ import android.util.Log; import java.util.HashMap; +/** + * 该类用于从设备联系人中根据电话号码获取联系人姓名,使用缓存机制提高性能。 + */ public class Contact { + // 静态的联系人缓存,用于存储已经查询过的电话号码及其对应的联系人姓名 private static HashMap sContactCache; + // 日志标签,用于在日志中标识该类的日志信息 private static final String TAG = "Contact"; + // 查询联系人的 SQL 选择语句模板 private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER - + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" - + " AND " + Data.RAW_CONTACT_ID + " IN " + + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" + + " AND " + Data.RAW_CONTACT_ID + " IN " + "(SELECT raw_contact_id " + " FROM phone_lookup" + " WHERE min_match = '+')"; + /** + * 根据电话号码从设备联系人中获取联系人姓名。 + * 如果联系人姓名已经在缓存中,则直接从缓存中获取; + * 否则,执行数据库查询,并将结果存入缓存。 + * + * @param context 应用程序上下文,用于访问内容解析器 + * @param phoneNumber 要查询的电话号码 + * @return 联系人姓名,如果未找到匹配的联系人则返回 null + */ public static String getContact(Context context, String phoneNumber) { + // 如果联系人缓存还未初始化,则创建一个新的 HashMap 用于存储缓存信息 if(sContactCache == null) { sContactCache = new HashMap(); } + // 检查缓存中是否已经存在该电话号码对应的联系人姓名 if(sContactCache.containsKey(phoneNumber)) { + // 如果存在,则直接从缓存中返回联系人姓名 return sContactCache.get(phoneNumber); } + // 将查询模板中的占位符 "+" 替换为电话号码的最小匹配格式 String selection = CALLER_ID_SELECTION.replace("+", PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); + + // 使用内容解析器查询联系人数据库 Cursor cursor = context.getContentResolver().query( - Data.CONTENT_URI, - new String [] { Phone.DISPLAY_NAME }, - selection, - new String[] { phoneNumber }, - null); + Data.CONTENT_URI, // 查询的数据 URI + new String [] { Phone.DISPLAY_NAME }, // 查询返回的列,这里只需要联系人姓名 + selection, // 查询的选择条件 + new String[] { phoneNumber }, // 选择条件的参数 + null); // 排序规则,这里使用默认排序 + // 如果查询结果不为空且游标可以移动到第一行 if (cursor != null && cursor.moveToFirst()) { try { + // 从游标中获取联系人姓名 String name = cursor.getString(0); + // 将电话号码和对应的联系人姓名存入缓存 sContactCache.put(phoneNumber, name); + // 返回联系人姓名 return name; } catch (IndexOutOfBoundsException e) { + // 如果获取联系人姓名时发生索引越界异常,记录错误日志 Log.e(TAG, " Cursor get string error " + e.toString()); + // 返回 null 表示未找到联系人姓名 return null; } finally { + // 无论查询结果如何,最后都要关闭游标以释放资源 cursor.close(); } } else { + // 如果查询结果为空,记录日志表示未找到匹配的联系人 Log.d(TAG, "No contact matched with number:" + phoneNumber); + // 返回 null 表示未找到联系人姓名 return null; } } -} +} \ No newline at end of file diff --git a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java index f240604..87ee7a7 100644 --- a/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java +++ b/src/Notesmaster/app/src/main/java/net/micode/notes/data/Notes.java @@ -17,263 +17,302 @@ package net.micode.notes.data; import android.net.Uri; + +/** + * 该类定义了笔记应用中使用的常量,包括笔记和文件夹的类型、系统文件夹的ID、 + * 意图额外数据的键名、内容URI以及数据库表的列名等。 + */ public class Notes { + // 内容提供者的授权信息,用于标识笔记应用的内容提供者 public static final String AUTHORITY = "micode_notes"; + // 日志标签,用于在日志中标识该类的相关信息 public static final String TAG = "Notes"; + // 笔记类型的常量值 public static final int TYPE_NOTE = 0; + // 文件夹类型的常量值 public static final int TYPE_FOLDER = 1; + // 系统类型的常量值 public static final int TYPE_SYSTEM = 2; /** - * Following IDs are system folders' identifiers - * {@link Notes#ID_ROOT_FOLDER } is default folder - * {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder - * {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records + * 以下ID是系统文件夹的标识符 + * {@link Notes#ID_ROOT_FOLDER } 是默认文件夹 + * {@link Notes#ID_TEMPARAY_FOLDER } 用于存放不属于任何文件夹的笔记 + * {@link Notes#ID_CALL_RECORD_FOLDER} 用于存储通话记录 */ + // 根文件夹的ID,作为默认文件夹 public static final int ID_ROOT_FOLDER = 0; + // 临时文件夹的ID,用于存放没有归属文件夹的笔记 public static final int ID_TEMPARAY_FOLDER = -1; + // 通话记录文件夹的ID,专门用于存储通话记录相关的笔记 public static final int ID_CALL_RECORD_FOLDER = -2; + // 回收站文件夹的ID,用于存放被删除的笔记或文件夹 public static final int ID_TRASH_FOLER = -3; + // 意图中传递提醒日期的额外数据键名 public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date"; + // 意图中传递笔记背景颜色ID的额外数据键名 public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id"; + // 意图中传递小部件ID的额外数据键名 public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id"; + // 意图中传递小部件类型的额外数据键名 public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type"; + // 意图中传递文件夹ID的额外数据键名 public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id"; + // 意图中传递通话日期的额外数据键名 public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date"; + // 无效小部件类型的常量值 public static final int TYPE_WIDGET_INVALIDE = -1; + // 2x尺寸小部件类型的常量值 public static final int TYPE_WIDGET_2X = 0; + // 4x尺寸小部件类型的常量值 public static final int TYPE_WIDGET_4X = 1; + /** + * 该静态内部类定义了数据相关的常量,主要是不同类型笔记的内容项类型。 + */ public static class DataConstants { + // 文本笔记的内容项类型 public static final String NOTE = TextNote.CONTENT_ITEM_TYPE; + // 通话笔记的内容项类型 public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE; } /** - * Uri to query all notes and folders + * 用于查询所有笔记和文件夹的内容URI */ public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note"); /** - * Uri to query data + * 用于查询数据的内容URI */ public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data"); + /** + * 该接口定义了笔记表的列名常量。 + */ public interface NoteColumns { /** - * The unique ID for a row - *

Type: INTEGER (long)

+ * 行的唯一ID + *

类型: INTEGER (long)

*/ public static final String ID = "_id"; /** - * The parent's id for note or folder - *

Type: INTEGER (long)

+ * 笔记或文件夹的父ID + *

类型: INTEGER (long)

*/ public static final String PARENT_ID = "parent_id"; /** - * Created data for note or folder - *

Type: INTEGER (long)

+ * 笔记或文件夹的创建日期 + *

类型: INTEGER (long)

*/ public static final String CREATED_DATE = "created_date"; /** - * Latest modified date - *

Type: INTEGER (long)

+ * 最新修改日期 + *

类型: INTEGER (long)

*/ public static final String MODIFIED_DATE = "modified_date"; - /** - * Alert date - *

Type: INTEGER (long)

+ * 提醒日期 + *

类型: INTEGER (long)

*/ public static final String ALERTED_DATE = "alert_date"; /** - * Folder's name or text content of note - *

Type: TEXT

+ * 文件夹名称或笔记的文本内容 + *

类型: TEXT

*/ public static final String SNIPPET = "snippet"; /** - * Note's widget id - *

Type: INTEGER (long)

+ * 笔记的小部件ID + *

类型: INTEGER (long)

*/ public static final String WIDGET_ID = "widget_id"; /** - * Note's widget type - *

Type: INTEGER (long)

+ * 笔记的小部件类型 + *

类型: INTEGER (long)

*/ public static final String WIDGET_TYPE = "widget_type"; /** - * Note's background color's id - *

Type: INTEGER (long)

+ * 笔记的背景颜色ID + *

类型: INTEGER (long)

*/ public static final String BG_COLOR_ID = "bg_color_id"; /** - * For text note, it doesn't has attachment, for multi-media - * note, it has at least one attachment - *

Type: INTEGER

+ * 对于文本笔记,没有附件;对于多媒体笔记,至少有一个附件 + *

类型: INTEGER

*/ public static final String HAS_ATTACHMENT = "has_attachment"; /** - * Folder's count of notes - *

Type: INTEGER (long)

+ * 文件夹中笔记的数量 + *

类型: INTEGER (long)

*/ public static final String NOTES_COUNT = "notes_count"; /** - * The file type: folder or note - *

Type: INTEGER

+ * 文件类型:文件夹或笔记 + *

类型: INTEGER

*/ public static final String TYPE = "type"; /** - * The last sync id - *

Type: INTEGER (long)

+ * 最后同步的ID + *

类型: INTEGER (long)

*/ public static final String SYNC_ID = "sync_id"; /** - * Sign to indicate local modified or not - *

Type: INTEGER

+ * 标记本地是否有修改 + *

类型: INTEGER

*/ public static final String LOCAL_MODIFIED = "local_modified"; /** - * Original parent id before moving into temporary folder - *

Type : INTEGER

+ * 移动到临时文件夹之前的原始父ID + *

类型 : INTEGER

*/ public static final String ORIGIN_PARENT_ID = "origin_parent_id"; /** - * The gtask id - *

Type : TEXT

+ * Google任务的ID + *

类型 : TEXT

*/ public static final String GTASK_ID = "gtask_id"; /** - * The version code - *

Type : INTEGER (long)

+ * 版本号 + *

类型 : INTEGER (long)

*/ public static final String VERSION = "version"; } + /** + * 该接口定义了数据表的列名常量。 + */ public interface DataColumns { /** - * The unique ID for a row - *

Type: INTEGER (long)

+ * 行的唯一ID + *

类型: INTEGER (long)

*/ public static final String ID = "_id"; /** - * The MIME type of the item represented by this row. - *

Type: Text

+ * 该行所代表项目的MIME类型 + *

类型: Text

*/ public static final String MIME_TYPE = "mime_type"; /** - * The reference id to note that this data belongs to - *

Type: INTEGER (long)

+ * 该数据所属笔记的引用ID + *

类型: INTEGER (long)

*/ public static final String NOTE_ID = "note_id"; /** - * Created data for note or folder - *

Type: INTEGER (long)

+ * 笔记或文件夹的创建日期 + *

类型: INTEGER (long)

*/ public static final String CREATED_DATE = "created_date"; /** - * Latest modified date - *

Type: INTEGER (long)

+ * 最新修改日期 + *

类型: INTEGER (long)

*/ public static final String MODIFIED_DATE = "modified_date"; /** - * Data's content - *

Type: TEXT

+ * 数据的内容 + *

类型: TEXT

*/ public static final String CONTENT = "content"; - /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for - * integer data type - *

Type: INTEGER

+ * 通用数据列,其含义与 {@link #MIMETYPE} 相关,用于整数类型的数据 + *

类型: INTEGER

*/ public static final String DATA1 = "data1"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for - * integer data type - *

Type: INTEGER

+ * 通用数据列,其含义与 {@link #MIMETYPE} 相关,用于整数类型的数据 + *

类型: INTEGER

*/ public static final String DATA2 = "data2"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for - * TEXT data type - *

Type: TEXT

+ * 通用数据列,其含义与 {@link #MIMETYPE} 相关,用于文本类型的数据 + *

类型: TEXT

*/ public static final String DATA3 = "data3"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for - * TEXT data type - *

Type: TEXT

+ * 通用数据列,其含义与 {@link #MIMETYPE} 相关,用于文本类型的数据 + *

类型: TEXT

*/ public static final String DATA4 = "data4"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for - * TEXT data type - *

Type: TEXT

+ * 通用数据列,其含义与 {@link #MIMETYPE} 相关,用于文本类型的数据 + *

类型: TEXT

*/ public static final String DATA5 = "data5"; } + /** + * 该静态内部类定义了文本笔记的相关常量。 + */ public static final class TextNote implements DataColumns { /** - * Mode to indicate the text in check list mode or not - *

Type: Integer 1:check list mode 0: normal mode

+ * 模式,用于指示文本是否处于复选列表模式 + *

类型: Integer 1: 复选列表模式 0: 正常模式

*/ public static final String MODE = DATA1; + // 复选列表模式的常量值 public static final int MODE_CHECK_LIST = 1; + // 文本笔记的内容类型 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note"; + // 文本笔记的内容项类型 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note"; + // 用于查询文本笔记的内容URI public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note"); } + /** + * 该静态内部类定义了通话笔记的相关常量。 + */ public static final class CallNote implements DataColumns { /** - * Call date for this record - *

Type: INTEGER (long)

+ * 该记录的通话日期 + *

类型: INTEGER (long)

*/ public static final String CALL_DATE = DATA1; /** - * Phone number for this record - *

Type: TEXT

+ * 该记录的电话号码 + *

类型: TEXT

*/ public static final String PHONE_NUMBER = DATA3; + // 通话笔记的内容类型 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; + // 通话笔记的内容项类型 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; + // 用于查询通话笔记的内容URI public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); } -} +} \ No newline at end of file