From d22b6b1243381cd884047ee78c248c730bac61ba Mon Sep 17 00:00:00 2001
From: phfuef3l9 <3117675914@qq.com>
Date: Tue, 23 Dec 2025 20:20:09 +0800
Subject: [PATCH] ADD Contact.java
---
Contact.java | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
create mode 100644 Contact.java
diff --git a/Contact.java b/Contact.java
new file mode 100644
index 0000000..bbcecaa
--- /dev/null
+++ b/Contact.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.data;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Data;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * 联系人查询工具类
+ *
+ * 主要负责根据电话号码从Android数据库中检索联系人姓名。
+ *
+ *
+ * 核心功能:
+ *
+ * - 基于电话号码查找姓名。
+ * - 维护 {@code HashMap} 缓存,减少 IPC 调用次数。
+ * - 处理国际化号码格式匹配问题。
+ *
+ *
+ * @author 林迪文
+ * @version 1.0
+ * @see android.provider.ContactsContract
+ */
+public class Contact {
+ //键值对,用于缓存<姓名,文本>,提高查找速度。
+ private static HashMap sContactCache;
+ //fianl意思是常量,TAG为Contact的“别名”。
+ private static final String TAG = "Contact";
+
+ //这是个SQL语句,CALLER_ID_SELECTION是个字符串,作用是构建匹配模式,用and连接了3个部分:电话匹配、数据类型需是电话、号码必须存在于快速查找表中
+ 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 " //Data哪来的
+ + "(SELECT raw_contact_id "
+ + " FROM phone_lookup"
+ + " WHERE min_match = '+')";
+
+ //主函数,输入电话,根据context,返回人名
+ public static String getContact(Context context, String phoneNumber) {
+ if(sContactCache == null) {
+ sContactCache = new HashMap();
+ } //初次调用getContact时,创建缓存
+
+ if(sContactCache.containsKey(phoneNumber)) {
+ return sContactCache.get(phoneNumber);
+ } //缓存命中
+
+ String selection = CALLER_ID_SELECTION.replace("+",
+ PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); //用处理过的电话号码,替代CALLER_ID_SELECTION的+。
+ Cursor cursor = context.getContentResolver().query(
+ Data.CONTENT_URI, //查找对象
+ new String [] { Phone.DISPLAY_NAME }, //需要返回的是名字这一列
+ selection, //查找条件
+ new String[] { phoneNumber }, //query可以将phoneNumber填到selection的'?'中
+ null); //不需排序
+
+ if (cursor != null && cursor.moveToFirst()) { //cursor.moveToFirst()为true代表至少有一条记录
+ 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.close(); //关闭进程,防止内存泄露
+ }
+ }
+ else {
+ Log.d(TAG, "No contact matched with number:" + phoneNumber); //没找到
+ return null;
+ }
+ }
+}