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.
git.text/src/data/Contact.java

136 lines
5.0 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;
/**
* <p>联系人信息查询和缓存类。</p>
* <p>核心职责:</p>
* <ul>
* <li>通过电话号码查询联系人姓名</li>
* <li>缓存查询结果以提高性能</li>
* <li>使用Android联系人API进行查询</li>
* </ul>
* <p>设计意图:</p>
* <ul>
* <li>提供便捷的联系人信息查询接口</li>
* <li>减少重复查询数据库的次数</li>
* <li>优化通话便签中显示联系人姓名的性能</li>
* </ul>
* <p>关键关联:</p>
* <ul>
* <li>使用{@link Context}访问系统联系人Content Provider</li>
* <li>使用{@link HashMap}实现查询结果缓存</li>
* <li>被通话便签功能使用,显示来电者姓名</li>
* </ul>
*/
public class Contact {
/**
* <p>联系人缓存,存储电话号码和联系人姓名的映射。</p>
* <p>业务含义:避免重复查询相同电话号码的联系人信息,提高性能。</p>
* <p>实现使用HashMap存储电话号码为键联系人为值。</p>
*/
private static HashMap<String, String> sContactCache;
/**
* <p>日志标签。</p>
* <p>业务含义用于在日志中标识Contact类的相关操作。</p>
*/
private static final String TAG = "Contact";
/**
* <p>联系人查询条件。</p>
* <p>业务含义定义查询联系人信息的SQL条件使用PHONE_NUMBERS_EQUAL函数匹配电话号码。</p>
* <p>注意:其中的'+'会在查询时被替换为实际的电话号码匹配模式。</p>
*/
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>
* <p>功能:通过电话号码查询手机通讯录中的联系人姓名,并缓存结果。</p>
*
* @param context 上下文对象用于访问ContentResolver
* @param phoneNumber 电话号码,用于查询联系人
*
* @return 联系人姓名如果未找到则返回null
*
* <p>查询流程:</p>
* <ol>
* <li>检查缓存中是否已存在该电话号码的联系人信息</li>
* <li>如果缓存中存在,直接返回缓存的联系人姓名</li>
* <li>如果缓存中不存在,构建查询条件</li>
* <li>通过ContentResolver查询联系人Content Provider</li>
* <li>如果查询成功,获取联系人姓名并缓存</li>
* <li>关闭Cursor</li>
* <li>返回查询结果</li>
* </ol>
*
* <p>错误处理:</p>
* <ul>
* <li>如果查询过程中发生IndexOutOfBoundsException记录错误日志并返回null</li>
* <li>如果未找到匹配的联系人记录调试日志并返回null</li>
* </ul>
*/
public static String getContact(Context context, String phoneNumber) {
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 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.close();
}
} else {
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}
}