Android通讯录管理(获取联系人、通话记录、短信消息)
2014年2月26日 通讯录开发研究学习
前言:前阵子主要是记录了如何对联系人的一些操作,比如搜索,全选、反选和删除等在实际开发中可能需要实现的功能,本篇博客是小巫从一个别人开源的一个项目抽取出来的部分内容,把它给简化出来,可以让需要的朋友清楚知道如何对Android数据库操作,异步查询数据库获取我们需要的内容。由于内容比较多,我将分三篇博客来讲述获取联系人、通话记录、短信消息的实现。

也许你根本就没耐心看,源码在这里http://download.csdn.net/detail/wwj_748/6962865,骚年去下吧。


上面的是获取联系人的界面效果,实现分组显示联系人,快速索引条查找联系人,下面是实现:
从权限开始:
                                



界面布局: /Contact_Demo/res/layout/contact_list_view.xml
<?xml version="1.0" encoding="utf-8"?>                            

/Contact_Demo/res/layout/contact_list_item.xml
<?xml version="1.0" encoding="utf-8"?>                        


代码实现:
1. 先定义一个实体类,用来保存联系人信息 /Contact_Demo/src/com/suntek/contact/model/ContactBean.java
package com.suntek.contact.model;public class ContactBean {private int contactId; //idprivate String desplayName;//姓名private String phoneNum; // 电话号码private String sortKey; // 排序用的private Long photoId; // 图片idprivate String lookUpKey; private int selected = 0;private String formattedNumber;private String pinyin; // 姓名拼音public int getContactId() {return contactId;}public void setContactId(int contactId) {this.contactId = contactId;}public String getDesplayName() {return desplayName;}public void setDesplayName(String desplayName) {this.desplayName = desplayName;}public String getPhoneNum() {return phoneNum;}public void setPhoneNum(String phoneNum) {this.phoneNum = phoneNum;}public String getSortKey() {return sortKey;}public void setSortKey(String sortKey) {this.sortKey = sortKey;}public Long getPhotoId() {return photoId;}public void setPhotoId(Long photoId) {this.photoId = photoId;}public String getLookUpKey() {return lookUpKey;}public void setLookUpKey(String lookUpKey) {this.lookUpKey = lookUpKey;}public int getSelected() {return selected;}public void setSelected(int selected) {this.selected = selected;}public String getFormattedNumber() {return formattedNumber;}public void setFormattedNumber(String formattedNumber) {this.formattedNumber = formattedNumber;}public String getPinyin() {return pinyin;}public void setPinyin(String pinyin) {this.pinyin = pinyin;}}


适配器: /Contact_Demo/src/com/suntek/contact/adapter/ContactListAdapter.java
package com.suntek.contact.adapter;import java.io.InputStream;import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Set;import java.util.regex.Pattern;import android.content.ContentUris;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.provider.ContactsContract;import android.provider.ContactsContract.Contacts;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.QuickContactBadge;import android.widget.TextView;import com.suntek.contact.R;import com.suntek.contact.model.ContactBean;import com.suntek.contact.view.QuickAlphabeticBar;public class ContactListAdapter extends BaseAdapter {private LayoutInflater inflater;private List list;private HashMap alphaIndexer; // 字母索引private String[] sections; // 存储每个章节private Context ctx; // 上下文public ContactListAdapter(Context context, List list,QuickAlphabeticBar alpha) {this.ctx = context;this.inflater = LayoutInflater.from(context);this.list = list;this.alphaIndexer = new HashMap();this.sections = new String[list.size()];for (int i = 0; i < list.size(); i++) {// 得到字母String name = getAlpha(list.get(i).getSortKey());if (!alphaIndexer.containsKey(name)) {alphaIndexer.put(name, i);}}Set sectionLetters = alphaIndexer.keySet();ArrayList sectionList = new ArrayList(sectionLetters);Collections.sort(sectionList); // 根据首字母进行排序sections = new String[sectionList.size()];sectionList.toArray(sections);alpha.setAlphaIndexer(alphaIndexer);}@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return position;}public void remove(int position) {list.remove(position);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = inflater.inflate(R.layout.contact_list_item, null);holder = new ViewHolder();holder.quickContactBadge = (QuickContactBadge) convertView.findViewById(R.id.qcb);holder.alpha = (TextView) convertView.findViewById(R.id.alpha);holder.name = (TextView) convertView.findViewById(R.id.name);holder.number = (TextView) convertView.findViewById(R.id.number);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ContactBean contact = list.get(position);String name = contact.getDesplayName();String number = contact.getPhoneNum();holder.name.setText(name);holder.number.setText(number);holder.quickContactBadge.assignContactUri(Contacts.getLookupUri(contact.getContactId(), contact.getLookUpKey()));if (0 == contact.getPhotoId()) {holder.quickContactBadge.setImageResource(R.drawable.touxiang);} else {Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contact.getContactId());InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(ctx.getContentResolver(), uri);Bitmap contactPhoto = BitmapFactory.decodeStream(input);holder.quickContactBadge.setImageBitmap(contactPhoto);}// 当前字母String currentStr = getAlpha(contact.getSortKey());// 前面的字母String previewStr = (position - 1) >= 0 ? getAlpha(list.get(position - 1).getSortKey()) : " ";if (!previewStr.equals(currentStr)) {holder.alpha.setVisibility(View.VISIBLE);holder.alpha.setText(currentStr);} else {holder.alpha.setVisibility(View.GONE);}return convertView;}private static class ViewHolder {QuickContactBadge quickContactBadge;TextView alpha;TextView name;TextView number;}/** * 获取首字母 *  * @param str * @return */private String getAlpha(String str) {if (str == null) {return "#";}if (str.trim().length() == 0) {return "#";}char c = str.trim().substring(0, 1).charAt(0);// 正则表达式匹配Pattern pattern = Pattern.compile("^[A-Za-z]+$");if (pattern.matcher(c + "").matches()) {return (c + "").toUpperCase(); // 将小写字母转换为大写} else {return "#";}}}


/Contact_Demo/src/com/suntek/contact/ContactListActivity.java
package com.suntek.contact;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.content.AsyncQueryHandler;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract;import android.view.View;import android.widget.ListView;import com.suntek.contact.adapter.ContactListAdapter;import com.suntek.contact.model.ContactBean;import com.suntek.contact.view.QuickAlphabeticBar;/** * 联系人列表 *  * @author Administrator *  */public class ContactListActivity extends Activity {private ContactListAdapter adapter;private ListView contactList;private List list;private AsyncQueryHandler asyncQueryHandler; // 异步查询数据库类对象private QuickAlphabeticBar alphabeticBar; // 快速索引条private Map contactIdMap = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.contact_list_view);contactList = (ListView) findViewById(R.id.contact_list);alphabeticBar = (QuickAlphabeticBar) findViewById(R.id.fast_scroller);// 实例化asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver());init();}/** * 初始化数据库查询参数 */private void init() {Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 联系人Uri;// 查询的字段String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key",ContactsContract.CommonDataKinds.Phone.CONTACT_ID,ContactsContract.CommonDataKinds.Phone.PHOTO_ID,ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY };// 按照sort_key升序查詢asyncQueryHandler.startQuery(0, null, uri, projection, null, null,"sort_key COLLATE LOCALIZED asc");}/** *  * @author Administrator *  */private class MyAsyncQueryHandler extends AsyncQueryHandler {public MyAsyncQueryHandler(ContentResolver cr) {super(cr);}@Overrideprotected void onQueryComplete(int token, Object cookie, Cursor cursor) {if (cursor != null && cursor.getCount() > 0) {contactIdMap = new HashMap();list = new ArrayList();cursor.moveToFirst(); // 游标移动到第一项for (int i = 0; i < cursor.getCount(); i++) {cursor.moveToPosition(i);String name = cursor.getString(1);String number = cursor.getString(2);String sortKey = cursor.getString(3);int contactId = cursor.getInt(4);Long photoId = cursor.getLong(5);String lookUpKey = cursor.getString(6);if (contactIdMap.containsKey(contactId)) {// 无操作} else {// 创建联系人对象ContactBean contact = new ContactBean();contact.setDesplayName(name);contact.setPhoneNum(number);contact.setSortKey(sortKey);contact.setPhotoId(photoId);contact.setLookUpKey(lookUpKey);list.add(contact);contactIdMap.put(contactId, contact);}}if (list.size() > 0) {setAdapter(list);}}super.onQueryComplete(token, cookie, cursor);}}private void setAdapter(List list) {adapter = new ContactListAdapter(this, list, alphabeticBar);contactList.setAdapter(adapter);alphabeticBar.init(ContactListActivity.this);alphabeticBar.setListView(contactList);alphabeticBar.setHight(alphabeticBar.getHeight());alphabeticBar.setVisibility(View.VISIBLE);}}

自定义组件:
package com.suntek.contact.view;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.LinearLayout;public class SlidingLinearLayout extends LinearLayout {public SlidingLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {return super.onInterceptTouchEvent(ev);}}


/Contact_Demo/src/com/suntek/contact/view/QuickAlphabeticBar.java
package com.suntek.contact.view;import java.util.HashMap;import android.app.Activity;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.os.Handler;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.ImageButton;import android.widget.ListView;import android.widget.TextView;import com.suntek.contact.R;/** * 字母索引条 *  * @author Administrator *  */public class QuickAlphabeticBar extends ImageButton {private TextView mDialogText; // 中间显示字母的文本框private Handler mHandler; // 处理UI的句柄private ListView mList; // 列表private float mHight; // 高度// 字母列表索引private String[] letters = new String[] { "#", "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 HashMap alphaIndexer;Paint paint = new Paint();boolean showBkg = false;int choose = -1;public QuickAlphabeticBar(Context context) {super(context);}public QuickAlphabeticBar(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public QuickAlphabeticBar(Context context, AttributeSet attrs) {super(context, attrs);}// 初始化public void init(Activity ctx) {mDialogText = (TextView) ctx.findViewById(R.id.fast_position);mDialogText.setVisibility(View.INVISIBLE);mHandler = new Handler();}// 设置需要索引的列表public void setListView(ListView mList) {this.mList = mList;}// 设置字母索引哈希表public void setAlphaIndexer(HashMap alphaIndexer) {this.alphaIndexer = alphaIndexer;}// 设置字母索引条的高度public void setHight(float mHight) {this.mHight = mHight;}@Overridepublic boolean onTouchEvent(MotionEvent event) {int act = event.getAction();float y = event.getY();final int oldChoose = choose;// 计算手指位置,找到对应的段,让mList移动段开头的位置上int selectIndex = (int) (y / (mHight / letters.length));if (selectIndex > -1 && selectIndex < letters.length) { // 防止越界String key = letters[selectIndex];if (alphaIndexer.containsKey(key)) {int pos = alphaIndexer.get(key);if (mList.getHeaderViewsCount() > 0) { // 防止ListView有标题栏,本例中没有this.mList.setSelectionFromTop(pos + mList.getHeaderViewsCount(), 0);} else {this.mList.setSelectionFromTop(pos, 0);}mDialogText.setText(letters[selectIndex]);}}switch (act) {case MotionEvent.ACTION_DOWN:showBkg = true;if (oldChoose != selectIndex) {if (selectIndex > 0 && selectIndex < letters.length) {choose = selectIndex;invalidate();}}if (mHandler != null) {mHandler.post(new Runnable() {@Overridepublic void run() {if (mDialogText != null&& mDialogText.getVisibility() == View.INVISIBLE) {mDialogText.setVisibility(VISIBLE);}}});}break;case MotionEvent.ACTION_MOVE:if (oldChoose != selectIndex) {if (selectIndex > 0 && selectIndex < letters.length) {choose = selectIndex;invalidate();}}break;case MotionEvent.ACTION_UP:showBkg = false;choose = -1;if (mHandler != null) {mHandler.post(new Runnable() {@Overridepublic void run() {if (mDialogText != null&& mDialogText.getVisibility() == View.VISIBLE) {mDialogText.setVisibility(INVISIBLE);}}});}break;default:break;}return super.onTouchEvent(event);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int height = getHeight();int width = getWidth();int sigleHeight = height / letters.length; // 单个字母占的高度for (int i = 0; i < letters.length; i++) {paint.setColor(Color.WHITE);paint.setTextSize(20);paint.setTypeface(Typeface.DEFAULT_BOLD);paint.setAntiAlias(true);if (i == choose) { paint.setColor(Color.parseColor("#00BFFF")); // 滑动时按下字母颜色paint.setFakeBoldText(true);}// 绘画的位置float xPos = width / 2 - paint.measureText(letters[i]) / 2;float yPos = sigleHeight * i + sigleHeight;canvas.drawText(letters[i], xPos, yPos, paint);paint.reset();}}}







更多相关文章

  1. android霓虹灯源代码――基础编
  2. Android(安卓)仿美团大众字母索引实现
  3. Android(安卓)获取所有联系人(两种方法)
  4. Android(安卓)选择联系人+返回对应手机号码
  5. Android短信管家(确认需求)1
  6. [置顶] Android中索引关联联系人
  7. Android切近实战(八)
  8. 仿Android联系人SideBar排序,根据拼音A-Z字母快速导航联系人姓名,
  9. Android(安卓)内置群组,联系人

随机推荐

  1. Android(安卓)Studio 3.6 Windos、mac最
  2. WakeLock & WifiLock的实现
  3. Ubuntu10.04系统 32位机上安装编译Androi
  4. android工程打成jar包
  5. itools官方下载2015 v3.1.7.0 中文版
  6. Android设备连接ZooKeeper服务器
  7. Android(安卓)模拟系统事件(一)
  8. android textView常用功能
  9. AlarmManager+Notification实现定时通知
  10. android中scrollTo和scrollBy的理解~~