You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xiangmuyi/Contact.java

95 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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;
// Contact类用于处理与联系人相关的操作主要功能是根据电话号码查找对应的联系人姓名并利用缓存机制提高查找效率
public class Contact {
// 用于缓存电话号码与对应的联系人姓名,避免重复查询联系人数据库,提高性能
private static HashMap<String, String> sContactCache;
// 用于在日志输出时标识当前类,方便调试查看相关日志信息
private static final String TAG = "Contact";
// 构建的一个SQL查询条件字符串用于从联系人数据库中筛选出与给定电话号码匹配的联系人记录
// 条件包括电话号码相等判断、数据类型匹配确保是电话号码类型的数据以及原始联系人ID相关的筛选条件等
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 = '+')";
// 该静态方法根据给定的上下文Context和电话号码phoneNumber尝试查找对应的联系人姓名
public static String getContact(Context context, String phoneNumber) {
// 如果缓存为空首次使用或者缓存被清空等情况则创建一个新的HashMap用于缓存联系人信息
if (sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
// 首先检查缓存中是否已经存在该电话号码对应的联系人姓名,如果存在则直接返回缓存中的姓名,避免再次查询数据库
if (sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
// 根据给定的电话号码,替换查询条件中的占位符,生成最终用于查询数据库的选择条件字符串
// 这里使用PhoneNumberUtils的方法将电话号码转换为合适的格式用于匹配查询例如处理号码格式等情况
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
// 通过上下文的ContentResolver发起一个数据库查询操作
// 查询的是联系人数据的统一资源标识符CONTENT_URI
// 只查询联系人的显示名称Phone.DISPLAY_NAME这一列数据
// 使用前面生成的选择条件selection并传入要查询匹配的电话号码作为参数
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String[]{Phone.DISPLAY_NAME},
selection,
new String[]{phoneNumber},
null);
// 如果游标不为空(表示查询到了数据)且游标可以移动到第一条记录(意味着有匹配的联系人记录)
if (cursor!= null && cursor.moveToFirst()) {
try {
// 从游标中获取第一列索引为0的数据即联系人的显示名称
String name = cursor.getString(0);
// 将获取到的电话号码和对应的联系人姓名存入缓存中,方便下次查询使用
sContactCache.put(phoneNumber, name);
// 返回查找到的联系人姓名
return name;
} catch (IndexOutOfBoundsException e) {
// 如果在获取游标数据时出现越界异常例如查询结果的列数不符合预期等情况记录错误日志并返回null
Log.e(TAG, " Cursor get string error " + e.toString());
return null;
} finally {
// 无论是否成功获取到联系人姓名,都需要关闭游标,释放相关资源
cursor.close();
}
} else {
// 如果没有查询到匹配的联系人记录记录一条调试日志表明没有找到与给定电话号码匹配的联系人然后返回null
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}
}