Android进阶之读取手机联系人显示listview并点击拨号(CursorAdapter)
2015-09-09 15:06
731 查看
一、CursorAdapter介绍
1、继承于BaseAdapter是个虚类,它为cursor和ListView提供了连接的桥梁。
如:public abstract class CursorAdapter extends BaseAdapter
2、注意cursor的必须要有个命名为”_id”的列。比如Contacts._ID就为”_id”
3、必须实现以下函数:
①newView(Context context, Cursor cursor, ViewGroup parent)
newView:并不是每次都被调用的,它只在实例化的时候调用,数据增加的时候也会调用,但是在重绘(比如修改条目里的TextView的内容)的时候不会被调用
②bindView(View view, Context context, Cursor cursor)
bindView:从代码中可以看出在绘制Item之前一定会调用bindView方法它在重绘的时候也同样被调用
4、更新ListView方法:adapter.changeCursor(cursor),它的功能类似于adapter.notifyDataSetChanged()方法
二、读取通讯录详解
1、权限
2、获取Cursor方法
3、为什么不使用Adapter继承于BaseAdapter?
因为Object对象不能转型为Cursor, 所以使用的Adapter继承于CursorAdapter,才能转型为CursorWrapper。
三、例子代码
1、AndroidManifest.xml
2、item_contact.xml
3、activity_contact.xml
4、ContactAdapter.java
5、ContactActivity.java
四、效果图
![](https://img-blog.csdn.net/20150909150621993)
五、推荐链接
Android中CursorAdapter的使用详解
android 读取手机通讯录并显示listview
Android之CursorAdapter用法
Android中读取短信信息
Android SMS 短信读取
1、继承于BaseAdapter是个虚类,它为cursor和ListView提供了连接的桥梁。
如:public abstract class CursorAdapter extends BaseAdapter
2、注意cursor的必须要有个命名为”_id”的列。比如Contacts._ID就为”_id”
3、必须实现以下函数:
①newView(Context context, Cursor cursor, ViewGroup parent)
newView:并不是每次都被调用的,它只在实例化的时候调用,数据增加的时候也会调用,但是在重绘(比如修改条目里的TextView的内容)的时候不会被调用
②bindView(View view, Context context, Cursor cursor)
bindView:从代码中可以看出在绘制Item之前一定会调用bindView方法它在重绘的时候也同样被调用
4、更新ListView方法:adapter.changeCursor(cursor),它的功能类似于adapter.notifyDataSetChanged()方法
二、读取通讯录详解
1、权限
<!-- 读取联系人权限 --> <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> <!-- 拨打电话权限 --> <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
2、获取Cursor方法
Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, PHONES_PROJECTION, null, null, null);
3、为什么不使用Adapter继承于BaseAdapter?
因为Object对象不能转型为Cursor, 所以使用的Adapter继承于CursorAdapter,才能转型为CursorWrapper。
/** * 点击监听实现 * * 实现:获得选中项的电话号码并拨号 */ private class onItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //从指针的封装类中获得选中项的电话号码并拨号 //返回值是Object类需要向下转型成CursorWrapper类型 CursorWrapper wrapper = (CursorWrapper) lvContact.getItemAtPosition(position - 1); //返回从0开始的索引,如果列名不存在将返回-1 int columnIndex = wrapper.getColumnIndex(Phone.NUMBER); if (!wrapper.isNull(columnIndex)) { String number = wrapper.getString(columnIndex); // 判断电话号码的有效性 if (PhoneNumberUtils.isGlobalPhoneNumber(number)) { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel://" + number)); startActivity(intent); } } } }
三、例子代码
1、AndroidManifest.xml
<!-- 读取联系人权限 --> <uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- 拨打电话权限 --> <uses-permission android:name="android.permission.CALL_PHONE" />
2、item_contact.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:orientation="horizontal" > <ImageView android:id="@+id/iv_head" android:layout_width="45dp" android:layout_height="45dp" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_marginLeft="8dp" android:orientation="horizontal" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:text="TextView" /> <TextView android:id="@+id/number" android:textSize="12sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" /> </LinearLayout> </LinearLayout> </LinearLayout> </LinearLayout>
3、activity_contact.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ListView android:id="@+id/lv_contact" android:layout_width="fill_parent" android:layout_height="fill_parent"> </ListView> </RelativeLayout>
4、ContactAdapter.java
package com.guan.contentproviderwork.contact; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.provider.ContactsContract; import android.support.v4.widget.CursorAdapter; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.guan.contentproviderwork.R; import java.io.InputStream; import java.util.ArrayList; import butterknife.Bind; import butterknife.ButterKnife; /** * 定义适配器 * CursorAdapter为cursor和ListView提供了连接的桥梁 * * @author Guan * @file com.guan.contentproviderwork * @date 2015/9/8 * @Version 1.0 */ public class ContactAdapter extends CursorAdapter { private Context mContext; /** * 联系人显示名称 */ private static final int PHONES_DISPLAY_NAME_INDEX = 1; /** * 电话号码 **/ private static final int PHONES_NUMBER_INDEX = 2; /** * 头像ID */ private static final int PHONES_PHOTO_ID_INDEX = 3; /** * 联系人的ID */ private static final int PHONES_CONTACT_ID_INDEX = 4; public ContactAdapter(Context context, Cursor cursor) { super(context,cursor); this.mContext = context; } @Override public int getCount() { if (mDataValid && mCursor != null) { return mCursor.getCount(); } else { return 0; } } @Override public Object getItem(int position) { if (mDataValid && mCursor != null) { mCursor.moveToPosition(position); return mCursor; } else { return null; } } @Override public long getItemId(int position) { if (mDataValid && mCursor != null) { if ( mCursor.moveToPosition(position)) { return mCursor.getLong( mRowIDColumn); } else { return 0; } } else { return 0; } } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView == null) { view = newView(mContext, mCursor, parent); } else { view = convertView; } bindView(view, mContext, mCursor); return view; } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { ViewHolder viewholder = null; View view = LayoutInflater.from(mContext).inflate( R.layout.item_contact, null); viewholder = new ViewHolder(view); view.setTag(viewholder); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { /** * 获取当前position * final int position=cursor.getPosition(); */ ViewHolder viewholder = (ViewHolder) view.getTag(); /** * 得到联系人名称 */ viewholder.name.setText(cursor.getString(PHONES_DISPLAY_NAME_INDEX) + ""); /** * 得到手机号码 */ viewholder.number.setText(cursor.getString(PHONES_NUMBER_INDEX) + ""); /** * 得到联系人头像 */ // 得到联系人ID Long contactid = cursor .getLong(PHONES_CONTACT_ID_INDEX); // 得到联系人头像ID Long photoid = cursor.getLong(PHONES_PHOTO_ID_INDEX); // 得到联系人头像Bitamp Bitmap contactPhoto = null; // photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的 if (photoid > 0) { Uri uri = ContentUris.withAppendedId( ContactsContract.Contacts.CONTENT_URI, contactid); InputStream input = ContactsContract.Contacts .openContactPhotoInputStream(mContext.getContentResolver(), uri); contactPhoto = BitmapFactory.decodeStream(input); } else { contactPhoto = BitmapFactory.decodeResource( mContext.getResources(), R.mipmap.ic_launcher); } viewholder.ivHead.setImageBitmap(contactPhoto); } /** * ViewHolder */ static class ViewHolder { @Bind(R.id.iv_head) ImageView ivHead; @Bind(R.id.name) TextView name; @Bind(R.id.number) TextView number; ViewHolder(View view) { ButterKnife.bind(this, view); } } }
5、ContactActivity.java
package com.guan.contentproviderwork.contact; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.database.CursorWrapper; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.telephony.PhoneNumberUtils; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import com.guan.contentproviderwork.R; import butterknife.Bind; import butterknife.ButterKnife; public class ContactActivity extends Activity { @Bind(R.id.lv_contact) ListView lvContact; /** * 联系人组 */ private static String[] PHONES_PROJECTION; /** * 联系人adapter */ private ContactAdapter mContactAdapter; /** * Curosr */ private Cursor mPhoneCursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact); ButterKnife.bind(this); // 初始化变量 initValiable(); // 获取联系人Cursor getCursor(); // 初始化listview bindData(); // 初始化监听 initListener(); } /** * 初始化变量 */ private void initValiable() { PHONES_PROJECTION = new String[]{ "_id", Phone.DISPLAY_NAME, Phone.NUMBER, Phone.PHOTO_ID, Phone.CONTACT_ID}; } /** * 获取所有联系人Cursor */ private Cursor getCursor() { ContentResolver resolver = getContentResolver(); mPhoneCursor = resolver.query(Phone.CONTENT_URI, PHONES_PROJECTION, null, null, null); return mPhoneCursor; } /** * 绑定数据 */ private void bindData() { mContactAdapter = new ContactAdapter(ContactActivity.this, mPhoneCursor); lvContact.setAdapter(mContactAdapter); } /** * 初始化监听 */ private void initListener() { lvContact.setOnItemClickListener(new onItemClickListener()); } /** * 点击监听实现 * <p/> * * 实现:获得选中项的电话号码并拨号 * * 注意:不能使用仅是继承于BaseAdapter,因为Object对象不能转型为Cursor。 * 所以:使用的Adapter是继承于CursorAdapter,才能转型为CursorWrapper。 */ private class onItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //从指针的封装类中获得选中项的电话号码并拨号 //返回值是Object类需要向下转型成CursorWrapper类型 CursorWrapper wrapper = (CursorWrapper) lvContact.getItemAtPosition(position - 1); //返回从0开始的索引,如果列名不存在将返回-1 int columnIndex = wrapper.getColumnIndex(Phone.NUMBER); if (!wrapper.isNull(columnIndex)) { String number = wrapper.getString(columnIndex); // 判断电话号码的有效性 if (PhoneNumberUtils.isGlobalPhoneNumber(number)) { Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel://" + number)); startActivity(intent); } } } } @Override protected void onDestroy() { super.onDestroy(); mPhoneCursor.close(); } /** // * 获取所有联系人 // */ // private void getPhoneContacts() { // // ContentResolver resolver = getContentResolver(); // try { // // 获取手机联系人 // mPhoneCursor = resolver.query(Phone.CONTENT_URI, // PHONES_PROJECTION, null, null, null); // if (mPhoneCursor != null) { // // while (mPhoneCursor.moveToNext()) { // // // 得到手机号码 // String phoneNumber = mPhoneCursor // .getString(PHONES_NUMBER_INDEX); // // 当手机号码为空的或者为空字段 跳过当前循环 // if (TextUtils.isEmpty(phoneNumber)) // continue; // // // 得到联系人名称 // String contactName = mPhoneCursor // .getString(PHONES_DISPLAY_NAME_INDEX); // // // 得到联系人ID // Long contactid = mPhoneCursor // .getLong(PHONES_CONTACT_ID_INDEX); // // // 得到联系人头像ID // Long photoid = mPhoneCursor.getLong(PHONES_PHOTO_ID_INDEX); // // // 得到联系人头像Bitamp // Bitmap contactPhoto = null; // // // photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的 // if (photoid > 0) { // Uri uri = ContentUris.withAppendedId( // ContactsContract.Contacts.CONTENT_URI, // contactid); // InputStream input = ContactsContract.Contacts // .openContactPhotoInputStream(resolver, uri); // contactPhoto = BitmapFactory.decodeStream(input); // } else { // contactPhoto = BitmapFactory.decodeResource( // getResources(), R.mipmap.ic_launcher); // } // ContactEntity mContact = new ContactEntity(contactName, // phoneNumber, contactPhoto); // mContacts.add(mContact); // } //// mPhoneCursor.close(); // } // } catch (Exception e) { // e.printStackTrace(); // } // } }
四、效果图
五、推荐链接
Android中CursorAdapter的使用详解
android 读取手机通讯录并显示listview
Android之CursorAdapter用法
Android中读取短信信息
Android SMS 短信读取
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories