您的位置:首页 > 移动开发 > Android开发

android 获取手机通讯录联系人,模拟通讯录显示

2016-04-14 17:05 651 查看
资源:点击打开链接

android 获取手机通讯录联系人,模拟通讯录显示
最近做项目,恰好有这样的需求;在网上搜搜,找到了许多相关的文章,但是多多少少有一些出入。现在整理一下,做个总结;有疑问可以@我!主要是获取手机通讯录,模拟手机通讯录的搜索、字母排序显示;
思路:
获取手机通讯录信息,对联系人名称进行处理,获取拼音、大写字母    
详情可以参考:http://blog.csdn.net/csh159/article/details/8955029/
直接上代码
</pre><pre name="code" class="java"><pre name="code" class="java">package com.example.sortlistview;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts.Photo;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.sortlistview.SideBar.OnTouchingLetterChangedListener;

public class MainActivity extends Activity {
private ListView sortListView;
private SideBar sideBar;
private TextView dialog;
private SortAdapter adapter;
private ClearEditText mClearEditText;

/**
* 汉字转换成拼音的类
*/
private CharacterParser characterParser;
private List<SortModel> SourceDateList;

/**
* 根据拼音来排列ListView里面的数据类
*/
private PinyinComparator pinyinComparator;
/** 联系人显示名称 **/
private static final int PHONES_DISPLAY_NAME_INDEX = 0;
/** 电话号码 **/
private static final int PHONES_NUMBER_INDEX = 1;
/** 头像ID **/
// private static final int PHONES_PHOTO_ID_INDEX = 2;
/** 联系人的ID **/
// private static final int PHONES_CONTACT_ID_INDEX = 3;

/** 库 phone表字段 **/
private static final String[] PHONES_PROJECTION = new String[] {
Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID, Phone.CONTACT_ID };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}

private void initViews() {
//实例化汉字转拼音类
characterParser = CharacterParser.getInstance();

pinyinComparator = new PinyinComparator();

sideBar = (SideBar) findViewById(R.id.sidrbar);
dialog = (TextView) findViewById(R.id.dialog);
sideBar.setTextView(dialog);

//设置右侧触摸监听
sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {

@Override
public void onTouchingLetterChanged(String s) {
//该字母首次出现的位置
int position = adapter.getPositionForSection(s.charAt(0));
if(position != -1){
sortListView.setSelection(position);
}

}
});

sortListView = (ListView) findViewById(R.id.country_lvcountry);
sortListView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//这里要利用adapter.getItem(position)来获取当前position所对应的对象
Toast.makeText(getApplication(), ((SortModel)adapter.getItem(position)).getName(), Toast.LENGTH_SHORT).show();
}
});

SourceDateList = loadPhoneContactData();

// 根据a-z进行排序源数据
Collections.sort(SourceDateList, pinyinComparator);
adapter = new SortAdapter(this, SourceDateList);
sortListView.setAdapter(adapter);

mClearEditText = (ClearEditText) findViewById(R.id.filter_edit);

//根据输入框输入值的改变来过滤搜索
mClearEditText.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
filterData(s.toString());
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void afterTextChanged(Editable s) {
}
});
}

/**
* 加载手机联系人
*/
private List<SortModel>  loadPhoneContactData() {

List<SortModel> mSortList = new ArrayList<SortModel>();

ContentResolver resolver = this.getContentResolver();
Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,
PHONES_PROJECTION, null, null, null);

SortModel sort = null;

String phoneNumber = "";

String phoneName = "";

// Long photoID = 0l;

if (phoneCursor != null) {

while (phoneCursor.moveToNext()) {

// get phone number
phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX)
.replace(" ", "");

if (phoneNumber==null||phoneNumber=="")
continue;

phoneName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);

sort = new SortModel();
sort.setMobile(phoneNumber);
sort.setName(phoneName);

// 汉字转换成拼音
String pinyin = characterParser.getSelling(phoneName);
String sortString = pinyin.substring(0, 1).toUpperCase();
sort.setSortLetters(sortString);

// 正则表达式,判断首字母是否是英文字母
if (sortString.matches("[A-Z]")) {
sort.setSortLetters(sortString.toUpperCase());
} else {
sort.setSortLetters("#");
}

mSortList.add(sort);
}

phoneCursor.close();

}

return mSortList;

}

/**
* 根据输入框中的值来过滤数据并更新ListView
* @param filterStr
*/
private void filterData(String filterStr){
List<SortModel> filterDateList = new ArrayList<SortModel>();

if(TextUtils.isEmpty(filterStr)){
filterDateList = SourceDateList;
}else{
filterDateList.clear();
for(SortModel sortModel : SourceDateList){
String name = sortModel.getName();
if(name.indexOf(filterStr.toString()) != -1 || characterParser.getSelling(name).startsWith(filterStr.toString())){
filterDateList.add(sortModel);
}
}
}

// 根据a-z进行排序
Collections.sort(filterDateList, pinyinComparator);
adapter.updateListView(filterDateList);
}

}

汉字转换为拼音,使用pinyin4j-2.5.0.jar库;之前使用的CharacterParser工具库是有bug的,例如“斐”是解析不出来的;

package com.example.sortlistview;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

public class ChineseToEnglish {
// 将汉字转换为全拼
public static String getPingYin(String src) {

char[] t1 = null;
t1 = src.toCharArray();
String[] t2 = new String[t1.length];
HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();

t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
t3.setVCharType(HanyuPinyinVCharType.WITH_V);
String t4 = "";
int t0 = t1.length;
try {
for (int i = 0; i < t0; i++) {
// 判断是否为汉字字符
if (java.lang.Character.toString(t1[i]).matches(
"[\\u4E00-\\u9FA5]+")) {
t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3);
t4 += t2[0];
} else
t4 += java.lang.Character.toString(t1[i]);
}
// System.out.println(t4);
return t4;
} catch (BadHanyuPinyinOutputFormatCombination e1) {
e1.printStackTrace();
}
return t4;
}

// 返回中文的首字母
public static String getPinYinHeadChar(String str) {

String convert = "";
for (int j = 0; j < str.length(); j++) {
char word = str.charAt(j);
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
if (pinyinArray != null) {
convert += pinyinArray[0].charAt(0);
} else {
convert += word;
}
}
return convert;
}

// 将字符串转移为ASCII码
public static String getCnASCII(String cnStr) {
StringBuffer strBuf = new StringBuffer();
byte[] bGBK = cnStr.getBytes();
for (int i = 0; i < bGBK.length; i++) {
strBuf.append(Integer.toHexString(bGBK[i] & 0xff));
}
return strBuf.toString();
}
}


搜索框 ClearEditText

package com.example.sortlistview;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;

public class ClearEditText extends EditText implements
OnFocusChangeListener, TextWatcher {
/**
* 删除按钮的引用
*/
private Drawable mClearDrawable;

public ClearEditText(Context context) {
this(context, null);
}

public ClearEditText(Context context, AttributeSet attrs) {
//这里构造方法也很重要,不加这个很多属性不能再XML里面定义
this(context, attrs, android.R.attr.editTextStyle);
}

public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init() {
//获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
mClearDrawable = getCompoundDrawables()[2];
if (mClearDrawable == null) {
mClearDrawable = getResources()
.getDrawable(R.drawable.emotionstore_progresscancelbtn);
}
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);
setOnFocusChangeListener(this);
addTextChangedListener(this);
}

/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在  EditText的宽度 - 图标到控件右边的间距 - 图标的宽度  和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getCompoundDrawables()[2] != null) {
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean touchable = event.getX() > (getWidth()
- getPaddingRight() - mClearDrawable.getIntrinsicWidth())
&& (event.getX() < ((getWidth() - getPaddingRight())));
if (touchable) {
this.setText("");
}
}
}

return super.onTouchEvent(event);
}

/**
* 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
*/
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
setClearIconVisible(getText().length() > 0);
} else {
setClearIconVisible(false);
}
}

/**
* 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
* @param visible
*/
protected void setClearIconVisible(boolean visible) {
Drawable right = visible ? mClearDrawable : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], right, getCompoundDrawables()[3]);
}

/**
* 当输入框里面内容发生变化的时候回调的方法
*/
@Override
public void onTextChanged(CharSequence s, int start, int count,
int after) {
setClearIconVisible(s.length() > 0);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void afterTextChanged(Editable s) {

}

/**
* 设置晃动动画
*/
public void setShakeAnimation(){
this.setAnimation(shakeAnimation(5));
}

/**
* 晃动动画
* @param counts 1秒钟晃动多少下
* @return
*/
public static Animation shakeAnimation(int counts){
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
translateAnimation.setInterpolator(new CycleInterpolator(counts));
translateAnimation.setDuration(1000);
return translateAnimation;
}

}


右侧字母侧边框 sideBar

package com.example.sortlistview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class SideBar extends View {
// 触摸事件
private OnTouchingLetterChangedListener onTouchingLetterChangedListener;
// 26个字母
public static String[] b = { "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z", "#" };
private int choose = -1;// 选中
private Paint paint = new Paint();

private TextView mTextDialog;

public void setTextView(TextView mTextDialog) {
this.mTextDialog = mTextDialog;
}

public SideBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

public SideBar(Context context, AttributeSet attrs) {
super(context, attrs);
}

public SideBar(Context context) {
super(context);
}

/**
* 重写这个方法
*/
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 获取焦点改变背景颜色.
int height = getHeight();// 获取对应高度
int width = getWidth(); // 获取对应宽度
int singleHeight = height / b.length;// 获取每一个字母的高度
canvas.drawColor(Color.argb(0,0,0,0));

for (int i = 0; i < b.length; i++) {
paint.setColor(Color.rgb(33, 65, 98));
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
paint.setTextSize(20);
// 选中的状态
if (i == choose) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
// x坐标等于中间-字符串宽度的一半.
float xPos = width / 2 - paint.measureText(b[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(b[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}

}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
final float y = event.getY();// 点击y坐标
final int oldChoose = choose;
final OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * b.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.

switch (action) {
case MotionEvent.ACTION_UP:
setBackgroundDrawable(new ColorDrawable(0x00000000));
//			choose = -1;
//			invalidate();
if (mTextDialog != null) {
mTextDialog.setVisibility(View.INVISIBLE);
}
break;

default:
setBackgroundDrawable(new ColorDrawable(0x00000000));
if (oldChoose != c) {
if (c >= 0 && c < b.length) {
if (listener != null) {
listener.onTouchingLetterChanged(b[c]);
}
if (mTextDialog != null) {
mTextDialog.setText(b[c]);
mTextDialog.setVisibility(View.VISIBLE);
}

choose = c;
invalidate();
}
}

break;
}
return true;
}

/**
* 向外公开的方法
*
* @param onTouchingLetterChangedListener
*/
public void setOnTouchingLetterChangedListener(
OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
}

/**
* 接口
*
* @author coder
*
*/
public interface OnTouchingLetterChangedListener {
public void onTouchingLetterChanged(String s);
}

}


联系人没有首字母特殊处理 PinyinComparator

package com.example.sortlistview;

import java.util.Comparator;

/**
* 联系人没有首字母特殊处理
* @author Administrator
*
*/
public class PinyinComparator implements Comparator<SortModel> {

public int compare(SortModel o1, SortModel o2) {
if (o1.getSortLetters().equals("@")
|| o2.getSortLetters().equals("#")) {
return -1;
} else if (o1.getSortLetters().equals("#")
|| o2.getSortLetters().equals("@")) {
return 1;
} else {
return o1.getSortLetters().compareTo(o2.getSortLetters());
}
}

}


联系人对象 SortModel

package com.example.sortlistview;

public class SortModel {

private String name;   //显示的数据
private String mobile;
private String sortLetters;  //显示数据拼音的首字母

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSortLetters() {
return sortLetters;
}
public void setSortLetters(String sortLetters) {
this.sortLetters = sortLetters;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}

}


数据显示格式定义类 SortAdapter

package com.example.sortlistview;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.SectionIndexer;
import android.widget.TextView;

public class SortAdapter extends BaseAdapter implements SectionIndexer{
private List<SortModel> list = null;
private Context mContext;

public SortAdapter(Context mContext, List<SortModel> list) {
this.mContext = mContext;
this.list = list;
}

/**
* 当ListView数据发生变化时,调用此方法来更新ListView
* @param list
*/
public void updateListView(List<SortModel> list){
this.list = list;
notifyDataSetChanged();
}

public int getCount() {
return this.list.size();
}

public Object getItem(int position) {
return list.get(position);
}

public long getItemId(int position) {
return position;
}

public View getView(final int position, View view, ViewGroup arg2) {
ViewHolder viewHolder = null;
final SortModel mContent = list.get(position);
if (view == null) {
viewHolder = new ViewHolder();
view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
viewHolder.tvTitle = (TextView) view.findViewById(R.id.title);
viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
viewHolder.tvPhone = (TextView) view.findViewById(R.id.phone);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}

//根据position获取分类的首字母的Char ascii值
int section = getSectionForPosition(position);

//如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
if(position == getPositionForSection(section)){
viewHolder.tvLetter.setVisibility(View.VISIBLE);
viewHolder.tvLetter.setText(mContent.getSortLetters());
}else{
viewHolder.tvLetter.setVisibility(View.GONE);
}

SortModel sort = this.list.get(position);

viewHolder.tvTitle.setText(sort.getName());
viewHolder.tvPhone.setText(sort.getMobile());

return view;

}

final static class ViewHolder {
TextView tvLetter;
TextView tvTitle;
TextView tvPhone;
}

/**
* 根据ListView的当前位置获取分类的首字母的Char ascii值
*/
public int getSectionForPosition(int position) {
return list.get(position).getSortLetters().charAt(0);
}

/**
* 根据分类的首字母的Char ascii值获取其第一次出现该首字母的位置
*/
public int getPositionForSection(int section) {
for (int i = 0; i < getCount(); i++) {
String sortStr = list.get(i).getSortLetters();
char firstChar = sortStr.toUpperCase().charAt(0);
if (firstChar == section) {
return i;
}
}

return -1;
}

/**
* 提取英文的首字母,非英文字母用#代替。
*
* @param str
* @return
*/
private String getAlpha(String str) {
String  sortStr = str.trim().substring(0, 1).toUpperCase();
// 正则表达式,判断首字母是否是英文字母
if (sortStr.matches("[A-Z]")) {
return sortStr;
} else {
return "#";
}
}

@Override
public Object[] getSections() {
return null;
}
}


主页activity布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<com.example.sortlistview.ClearEditText
android:id="@+id/filter_edit"
android:layout_marginTop="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/search_bar_edit_selector"
android:drawableLeft="@drawable/search_bar_icon_normal"
android:hint="请输入关键字"
android:singleLine="true"
android:textSize="15.0dip" />

<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<ListView
android:id="@+id/country_lvcountry"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:divider="@null" />

<TextView
android:id="@+id/dialog"
android:layout_width="80.0dip"
android:layout_height="80.0dip"
android:layout_gravity="center"
android:background="@drawable/show_head_toast_bg"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="30.0dip"
android:visibility="invisible" />

<com.example.sortlistview.SideBar
android:id="@+id/sidrbar"
android:layout_width="30.0dip"
android:layout_height="fill_parent"
android:layout_gravity="right|center" />
</FrameLayout>

</LinearLayout>


数据显示item 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical" >

<TextView
android:id="@+id/catalog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#E0E0E0"
android:textColor="#454545"
android:layout_weight="1.0"
android:paddingLeft="5dip"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:text="A"/>

<LinearLayout
android:id="@+id/contachInfo"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:gravity="center_vertical"
android:orientation="horizontal" >

<ImageView
android:id="@+id/imgHead"
android:layout_width="40dip"
android:layout_height="40dip"
android:src="@drawable/default_avatar"
android:paddingLeft="5dip" />

<LinearLayout
android:id="@+id/phoneLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="5dip"
android:layout_marginLeft="5dip" >

<TextView
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:gravity="bottom"
android:layout_weight="1.0"
android:textColor="#000000"
android:textSize="12sp"
android:text="hhhh"/>

<TextView
android:id="@+id/phone"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:layout_weight="1.0"
android:textColor="#000000"
android:textSize="12sp"
android:text="电话号码"/>
</LinearLayout>
</LinearLayout>

</LinearLayout>


活动窗口:

package com.example.sortlistview;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts.Photo;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.sortlistview.SideBar.OnTouchingLetterChangedListener;

public class MainActivity extends Activity {
private ListView sortListView;
private SideBar sideBar;
private TextView dialog;
private SortAdapter adapter;
private ClearEditText mClearEditText;

/**
* 汉字转换成拼音的类
*/
private CharacterParser characterParser;
private List<SortModel> SourceDateList;

/**
* 根据拼音来排列ListView里面的数据类
*/
private PinyinComparator pinyinComparator;
/** 联系人显示名称 **/
private static final int PHONES_DISPLAY_NAME_INDEX = 0;
/** 电话号码 **/
private static final int PHONES_NUMBER_INDEX = 1;
/** 头像ID **/
// private static final int PHONES_PHOTO_ID_INDEX = 2;
/** 联系人的ID **/
// private static final int PHONES_CONTACT_ID_INDEX = 3;

/** 库 phone表字段 **/
private static final String[] PHONES_PROJECTION = new String[] {
Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID, Phone.CONTACT_ID };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}

private void initViews() {
//实例化汉字转拼音类
characterParser = CharacterParser.getInstance();

pinyinComparator = new PinyinComparator();

sideBar = (SideBar) findViewById(R.id.sidrbar);
dialog = (TextView) findViewById(R.id.dialog);
sideBar.setTextView(dialog);

//设置右侧触摸监听
sideBar.setOnTouchingLetterChangedListener(new OnTouchingLetterChangedListener() {

@Override
public void onTouchingLetterChanged(String s) {
//该字母首次出现的位置
int position = adapter.getPositionForSection(s.charAt(0));
if(position != -1){
sortListView.setSelection(position);
}

}
});

sortListView = (ListView) findViewById(R.id.country_lvcountry);
sortListView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//这里要利用adapter.getItem(position)来获取当前position所对应的对象
Toast.makeText(getApplication(), ((SortModel)adapter.getItem(position)).getName(), Toast.LENGTH_SHORT).show();
}
});

SourceDateList = loadPhoneContactData();

// 根据a-z进行排序源数据
Collections.sort(SourceDateList, pinyinComparator);
adapter = new SortAdapter(this, SourceDateList);
sortListView.setAdapter(adapter);

mClearEditText = (ClearEditText) findViewById(R.id.filter_edit);

//根据输入框输入值的改变来过滤搜索
mClearEditText.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
filterData(s.toString());
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void afterTextChanged(Editable s) {
}
});
}

/**
* 加载手机联系人
*/
private List<SortModel>  loadPhoneContactData() {

List<SortModel> mSortList = new ArrayList<SortModel>();

ContentResolver resolver = this.getContentResolver();
Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,
PHONES_PROJECTION, null, null, null);

SortModel sort = null;

String phoneNumber = "";

String phoneName = "";

// Long photoID = 0l;

if (phoneCursor != null) {

while (phoneCursor.moveToNext()) {

// get phone number
phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX)
.replace(" ", "");

if (phoneNumber==null||phoneNumber=="")
continue;

phoneName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);

sort = new SortModel();
sort.setMobile(phoneNumber);
sort.setName(phoneName);

// 汉字转换成拼音
String pinyin = characterParser.getSelling(phoneName);
String sortString = pinyin.substring(0, 1).toUpperCase();
sort.setSortLetters(sortString);

// 正则表达式,判断首字母是否是英文字母
if (sortString.matches("[A-Z]")) {
sort.setSortLetters(sortString.toUpperCase());
} else {
sort.setSortLetters("#");
}

mSortList.add(sort);
}

phoneCursor.close();

}

return mSortList;

}

/**
* 根据输入框中的值来过滤数据并更新ListView
* @param filterStr
*/
private void filterData(String filterStr){
List<SortModel> filterDateList = new ArrayList<SortModel>();

if(TextUtils.isEmpty(filterStr)){
filterDateList = SourceDateList;
}else{
filterDateList.clear();
for(SortModel sortModel : SourceDateList){
String name = sortModel.getName();
if(name.indexOf(filterStr.toString()) != -1 || characterParser.getSelling(name).startsWith(filterStr.toString())){
filterDateList.add(sortModel);
}
}
}

// 根据a-z进行排序
Collections.sort(filterDateList, pinyinComparator);
adapter.updateListView(filterDateList);
}

}


AndroidManifest.xml文件,说明一下,获取手机通讯录,必须添加通讯录访问权限;即

<uses-permission android:name="android.permission.READ_CONTACTS" />


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sortlistview"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="23" />

<uses-permission android:name="android.permission.READ_CONTACTS" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.sortlistview.MainActivity"
android:windowSoftInputMode = "adjustPan"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


运行效果图:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: