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.
MiNoteRead/src/Notes-master/src/net/micode/notes/data/Contact.java

119 lines
5.2 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;
/**
* 联系人查询工具类
* 核心功能:在小米便签中用于智能识别电话号码并显示联系人名称
* 实现方法:通过电话号码查询系统联系人的姓名,并通过哈希表缓存查询结果,避免重复查询,提升性能
*/
public class Contact {
// 功能:缓存查询结果,,暂时存储电话号码与联系人的映射关系,避免重复查询,节省开销
private static HashMap<String, String> sContactCache;
// 日志标签
private static final String TAG = "Contact";
// 查询联系人的选择条件
*/
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_lookupAndroid系统中的一个与联系人数据有关的特殊表
* min_match最小匹配位数
* 预先计算一个电话号码的最小匹配形式的表格
*/
/**
* 根据电话号码获取联系人姓名。
*
* @param context 上下文对象,用于访问 ContentResolver
* @param phoneNumber 电话号码(原始字符串,不做预处理)
* @return 联系人姓名;未找到或异常时返回 null
*/
public static String getContact(Context context, String phoneNumber) {
// 如果缓存哈希表为空,则创建新的哈希表
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
// 检查缓存中是否已有该电话号码对应的联系人
// 检查缓存中是否已存在该电话号码的查询结果
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
// 构建查询条件替换min_match参数
// PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)用于计算电话号码的最小匹配位数
// 将占位符"+"替换为最小匹配数,以构建完整的查询语句
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
/**
* 查询联系人数据库
* context.getContentResolver().query查询当前应用程序的数据
*/
Cursor cursor = context.getContentResolver().query(
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;
}
}
}