diff --git a/src/Notes-master/src/net/micode/notes/data/Contact.java b/src/Notes-master/src/net/micode/notes/data/Contact.java index d97ac5d..6850334 100644 --- a/src/Notes-master/src/net/micode/notes/data/Contact.java +++ b/src/Notes-master/src/net/micode/notes/data/Contact.java @@ -25,47 +25,94 @@ import android.util.Log; import java.util.HashMap; +/** + * 联系人查询工具类 + * 核心功能:在小米便签中用于智能识别电话号码并显示联系人名称 + * 实现方法:通过电话号码查询系统联系人的姓名,并通过哈希表缓存查询结果,避免重复查询,提升性能 + * + */ public class Contact { + // 功能:缓存查询结果,,暂时存储电话号码与联系人的映射关系,避免重复查询,节省开销 private static HashMap sContactCache; + // 日志标签为Contact 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 " + "(SELECT raw_contact_id " + " FROM phone_lookup" + " WHERE min_match = '+')"; + /** + * SQL语句逻辑解读 + * AND 连接一个条件与下一个条件 + * 第一个条件:PHONE_NUMBERS_EQUAL(Phone.NUMBER,?) + * PHONE_NUMBERS_EQUAL 函数:Android系统提供的特殊函数,用于查找和Phone.NUMBER相同的电话号码 + * 第二个条件:Data.MIMETYPE = 'Phone.CONTENT_ITEM_TYPE' + * 确保数据类型必须是电话号码类型 + * 第三个条件:Data.RAW_CONTACT_ID IN A + * 联系人的ID必须存在于这个表格A中 + * 表格A:(SELECT raw_contact_id FROM phone_lookup WHERE min_match = '+') + * phone_lookup:Android系统中的一个与联系人数据有关的特殊表 + * min_match:最小匹配位数 + * 预先计算一个电话号码的最小匹配形式的表格 + */ + /** + * getContact函数:查询联系人的姓名 + * @param context Android应用程序上下文 + * @param phoneNumber 要查询的电话号码 + * @return 联系人姓名,如果查询不到则返回null + */ public static String getContact(Context context, String phoneNumber) { + // 初始化查询缓存 if(sContactCache == null) { sContactCache = new HashMap(); } + // 检查缓存中是否已存在该电话号码的查询结果 if(sContactCache.containsKey(phoneNumber)) { return sContactCache.get(phoneNumber); } + // PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)用于计算电话号码的最小匹配位数 + // 将占位符"+"替换为最小匹配数,以构建完整的查询语句 String selection = CALLER_ID_SELECTION.replace("+", PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); + + /** + * 查询联系人数据库 + * context.getContentResolver().query:查询当前应用程序的数据 + */ 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中 Log.e(TAG, " Cursor get string error " + e.toString()); return null; } finally { + // 关闭Cursor,防止内存泄露 cursor.close(); } } else { + // 没有找到匹配的联系人,将信息写入日志中 Log.d(TAG, "No contact matched with number:" + phoneNumber); return null; }