Android通讯录模糊查询搜索(号码,姓名,首字母简拼,全拼),批量选取联系人


  公司最近的项目中遇到一个需求需要读取通讯录联系人,并需要支持对联系人的模糊查询及批量选取,网上找了好几个例子,模糊查询这块处理的都有点小瑕疵,最终自己在各位网友的辛勤贡献基础之上进行了优化,最终做出了联系人模糊查询. 支持以下功能:


1.按 号码 , 姓名 , 首字母简拼 , 全拼 模糊查询
2.支持[A-Z]快速导航

3.支持联系人按首字母分类

4.支持联系人批量选取.


最新代码详见,具体github地址:  https://github.com/cuixbo/FuzzyQueryContacts
界面如下:


代码结构:

主要代码:
ContactsActivity:
package com.xbc.utils.activity;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Locale;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.os.Bundle;import android.provider.ContactsContract.CommonDataKinds.Phone;import android.text.Editable;import android.text.TextUtils;import android.text.TextWatcher;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.EditText;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import com.xbc.contacts.R;import com.xbc.utils.activity.ContactsSortAdapter.ViewHolder;import com.xbc.utils.activity.SideBar.OnTouchingLetterChangedListener;public class ContactsActivity extends Activity {ListView mListView;EditText etSearch;ImageView ivClearText;private SideBar sideBar;private TextView dialog;private List mAllContactsList;private ContactsSortAdapter adapter;/** * 汉字转换成拼音的类 */private CharacterParser characterParser;/** * 根据拼音来排列ListView里面的数据类 */private PinyinComparator pinyinComparator;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_contacts);init();}private void init() {initView();initListener();loadContacts();}private void initListener() {/**清除输入字符**/ivClearText.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {etSearch.setText("");}});etSearch.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}@Overridepublic void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {}@Overridepublic void afterTextChanged(Editable e) {String content = etSearch.getText().toString();if ("".equals(content)) {ivClearText.setVisibility(View.INVISIBLE);} else {ivClearText.setVisibility(View.VISIBLE);}if (content.length() > 0) {ArrayList fileterList = (ArrayList) search(content);adapter.updateListView(fileterList);//mAdapter.updateData(mContacts);} else {adapter.updateListView(mAllContactsList);}mListView.setSelection(0);}});//设置右侧[A-Z]快速导航栏触摸监听sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {@Overridepublic void onTouchingLetterChanged(String s) {//该字母首次出现的位置int position = adapter.getPositionForSection(s.charAt(0));if (position != -1) {mListView.setSelection(position);}}});mListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int position, long arg3) {ViewHolder viewHolder = (ViewHolder) view.getTag();viewHolder.cbChecked.performClick();adapter.toggleChecked(position);}});}private void initView() {sideBar = (SideBar) findViewById(R.id.sidrbar);dialog = (TextView) findViewById(R.id.dialog);sideBar.setTextView(dialog);ivClearText = (ImageView) findViewById(R.id.ivClearText);etSearch = (EditText) findViewById(R.id.et_search);mListView = (ListView) findViewById(R.id.lv_contacts);/** 给ListView设置adapter **/characterParser = CharacterParser.getInstance();mAllContactsList = new ArrayList();pinyinComparator = new PinyinComparator();Collections.sort(mAllContactsList, pinyinComparator);// 根据a-z进行排序源数据adapter = new ContactsSortAdapter(this, mAllContactsList);mListView.setAdapter(adapter);}private void loadContacts() {new Thread(new Runnable() {@Overridepublic void run() {try {ContentResolver resolver = getApplicationContext().getContentResolver();Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, new String[] { Phone.DISPLAY_NAME, Phone.NUMBER, "sort_key" }, null, null, "sort_key COLLATE LOCALIZED ASC");if (phoneCursor == null || phoneCursor.getCount() == 0) {Toast.makeText(getApplicationContext(), "未获得读取联系人权限 或 未获得联系人数据", Toast.LENGTH_SHORT).show();return;}int PHONES_NUMBER_INDEX = phoneCursor.getColumnIndex(Phone.NUMBER);int PHONES_DISPLAY_NAME_INDEX = phoneCursor.getColumnIndex(Phone.DISPLAY_NAME);int SORT_KEY_INDEX = phoneCursor.getColumnIndex("sort_key");if (phoneCursor.getCount() > 0) {mAllContactsList = new ArrayList();while (phoneCursor.moveToNext()) {String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);if (TextUtils.isEmpty(phoneNumber))continue;String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);String sortKey = phoneCursor.getString(SORT_KEY_INDEX);//System.out.println(sortKey);SortModel sortModel = new SortModel(contactName, phoneNumber, sortKey);//优先使用系统sortkey取,取不到再使用工具取String sortLetters = getSortLetterBySortKey(sortKey);if (sortLetters == null) {sortLetters = getSortLetter(contactName);}sortModel.sortLetters = sortLetters;sortModel.sortToken = parseSortKey(sortKey);mAllContactsList.add(sortModel);}}phoneCursor.close();runOnUiThread(new Runnable() {public void run() {Collections.sort(mAllContactsList, pinyinComparator);adapter.updateListView(mAllContactsList);}});} catch (Exception e) {Log.e("xbc", e.getLocalizedMessage());}}}).start();}/** * 名字转拼音,取首字母 * @param name * @return */private String getSortLetter(String name) {String letter = "#";if (name == null) {return letter;}//汉字转换成拼音String pinyin = characterParser.getSelling(name);String sortString = pinyin.substring(0, 1).toUpperCase(Locale.CHINESE);// 正则表达式,判断首字母是否是英文字母if (sortString.matches("[A-Z]")) {letter = sortString.toUpperCase(Locale.CHINESE);}return letter;}/** * 取sort_key的首字母 * @param sortKey * @return */private String getSortLetterBySortKey(String sortKey) {if (sortKey == null || "".equals(sortKey.trim())) {return null;}String letter = "#";//汉字转换成拼音String sortString = sortKey.trim().substring(0, 1).toUpperCase(Locale.CHINESE);// 正则表达式,判断首字母是否是英文字母if (sortString.matches("[A-Z]")) {letter = sortString.toUpperCase(Locale.CHINESE);}return letter;}/** * 模糊查询 * @param str * @return */private List search(String str) {List filterList = new ArrayList();//过滤后的listif (str.matches("^([0-9]|[/+])*$")) {//正则表达式 匹配号码for (SortModel contact : mAllContactsList) {if (contact.number != null && contact.name != null) {if (contact.number.contains(str) || contact.name.contains(str)) {if (!filterList.contains(contact)) {filterList.add(contact);}}}}} else {for (SortModel contact : mAllContactsList) {if (contact.number != null && contact.name != null) {//姓名全匹配,姓名首字母简拼匹配,姓名全字母匹配if (contact.name.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))|| contact.sortKey.toLowerCase(Locale.CHINESE).replace(" ", "").contains(str.toLowerCase(Locale.CHINESE))|| contact.sortToken.simpleSpell.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))|| contact.sortToken.wholeSpell.toLowerCase(Locale.CHINESE).contains(str.toLowerCase(Locale.CHINESE))) {if (!filterList.contains(contact)) {filterList.add(contact);}}}}}return filterList;}String chReg = "[\\u4E00-\\u9FA5]+";//中文字符串匹配//String chReg="[^\\u4E00-\\u9FA5]";//除中文外的字符匹配/** * 解析sort_key,封装简拼,全拼 * @param sortKey * @return */public SortToken parseSortKey(String sortKey) {SortToken token = new SortToken();if (sortKey != null && sortKey.length() > 0) {//其中包含的中文字符String[] enStrs = sortKey.replace(" ", "").split(chReg);for (int i = 0, length = enStrs.length; i < length; i++) {if (enStrs[i].length() > 0) {//拼接简拼token.simpleSpell += enStrs[i].charAt(0);token.wholeSpell += enStrs[i];}}}return token;}}


更多相关文章

  1. android学习之获取联系人原理(姓名和电话)详解
  2. android 验证码按钮点击,判断网络和匹配手机号并自动更新时间;
  3. Android短信会话(查看会话记录以及会话详情界面)---短信管家3
  4. Android比iPhone强在哪里?我的个人使用感官
  5. Android实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼
  6. Android通讯录开发之通讯录联系人搜索功能最新实现
  7. Pattern.compile
  8. 根据IP地址定位城市
  9. 线程池运行多个线程

随机推荐

  1. Android布局优化----ViewStub、include、
  2. Intellij IDEA + Android SDK + Genymoti
  3. 关于android的反射机制的用法
  4. Android SQLite3工具常用命令行总结
  5. Android录音
  6. android dialog 点击不消失
  7. 恶心的Android 蓝牙
  8. Android之Chronometer
  9. 如何使Android录音实现内录功能
  10. Android 蓝牙移植笔记