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.
xiaomi_notes_reading/src/notes/data/Contact.java

107 lines
4.2 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden 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.
*/
/*
*文件名Contact.java
* 修改人:蒙程
* 修改时间2025-12-13
* 修改内容增加代码注释标注的代码行数共有21行
*/
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类是联系人工具类
*
*<P>根据“提供的电话号码反向查询联系人姓名”的能力,并带内存缓存,避免重复查库。</P>
* 本类所有方法均为静态,无需实例化。
*
* @author 蒙程
* @version 1.0
* @since [起始版本]
*/
public class Contact {
//HashMap表示联系人和电话号码之间的映射关系。只声明不new是延迟初始化的表现
private static HashMap<String, String> sContactCache;
private static final String TAG = "Contact";
//说明电话号码格式可兼容国际区号、前缀0等多种格式
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 = '+')";
/**
* 根据电话号码获取联系人姓名
* <P>优先读取内存缓存,未命中时查询系统联系人数据库,并将结果写入缓存。</P>
* @param context 上下文用于访问ContentResolver
* @param phoneNumber 待查询的电话号码(可为国际格式、带前缀 0 等)
* @return 联系人姓名未匹配到或者发生异常时返回code null
* @throws
* @see android.provider.ContactsContract.CommonDataKinds
*/
public static String getContact(Context context, String phoneNumber) {
//不到真正要用的时候不给对象分配内存。第一次被调用时才new。
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
//缓存命中,直接返回电话号码
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
//构造匹配串,提取数字核心部分
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
//cursor是数据库游标初始位置是-1query把SQL拼装好后交给系统联系人Provider
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String [] { Phone.DISPLAY_NAME },
selection,
new String[] { phoneNumber },
null);
//指针移到第一行成功返回true
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 { //查询失败,输出日志信息
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}
}