
// 包路径
package net.micode.notes.data;

// 导入的类

import android.content.Context; // 提供应用程序环境的全局信息，如资源、启动活动、接收广播等
import android.database.Cursor; // 用于对数据库查询结果进行读取和遍历的接口
import android.provider.ContactsContract.CommonDataKinds.Phone; // 定义联系人电话信息的数据结构和常量
import android.provider.ContactsContract.Data; // 定义用于访问Android联系人数据表的常量
import android.telephony.PhoneNumberUtils; // 提供电话号码相关的实用程序方法，如格式化
import android.util.Log; // Android日志工具类，用于打印日志信息
import java.util.HashMap;// 联系人类，用于管理联系人信息
public class Contact {
    // 缓存联系人名称与电话号码的映射关系
    private static HashMap<String, String> sContactCache;
    // 类的标签，用于Log输出，缓存电话号码和联系人名称的对应关系
    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 = '+')";

    // 根据电话号码查询联系人名称
    public static String getContact(Context context, String phoneNumber) {
        // 如果联系人缓存不存在，则实例化它
        if(sContactCache == null) {
            sContactCache = new HashMap<String, String>();
        }

        // 如果缓存中包含指定的电话号码，则直接返回缓存中的联系人名称
        if(sContactCache.containsKey(phoneNumber)) {
            return sContactCache.get(phoneNumber);
        }

        // 替换SQL选择语句中的占位符为电话号码的匹配模式
        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);

        // 如果查询结果不为空，且至少包含一条记录
        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());
                return null;
            } finally {
                // 确保在最后关闭Cursor对象释放资源
                cursor.close();
            }
        } else {
            // 如果没有找到匹配的联系人，记录信息并返回null
            Log.d(TAG, "No contact matched with number:" + phoneNumber);
            return null;
        }
    }
}
//用于与联系人相关数据交互的助手类。该类主要目的是从设备的联系人数据库中检索并缓存联系人名称。
//核心操作是 `getContact` 函数，它检查给定电话号码是否已缓存。如果没有，在联系人数据库中查找匹配的联系人，并将结果缓存以加速后续查询。
//在 `getContact` 函数中，代码通过查询Android的联系人数据库来获取电话号码对应的显示名称。查询使用了特定的选择字符串 `CALLER_ID_SELECTION`，其中采用了匹配电话号码的过滤条件。
//当找到匹配的电话号码时，联系人名称会被放入缓存中并返回。如果没有找到匹配项或查询过程中发生异常，将会记录相应的日志。