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

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、权限

<!-- 读取联系人权限 -->
<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 短信读取
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android listview cursor