基于PinnedSectionListView实现联系人通讯录并且点击打电话



<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"
     >

    <com.zzw.contacts.PinnedSectionListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

activity_main.xml

权限:

 <!-- 写权限 -->
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <!-- 读权限 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <!-- 打电话权限 -->
    <uses-permission android:name="android.permission.CALL_PHONE" />
package com.zzw.contacts;

import java.util.ArrayList;

import com.zzw.contacts.PinnedSectionListView.PinnedSectionListAdapter;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        ArrayList<Contact> contacts = new ArrayList<Contact>();
        readContacts(contacts);

        final ArrayList<Item> items = new ArrayList<Item>();

        // 从字母A开始到Z。26个字母,遍历联系人中的首字符是否相等。
        // 相等则归入一组。
        int A = (int) 'A';
        for (int i = 0; i < 26; i++) {
            int letter = A + i;
            char c = (char) letter;

            Item group = new Item();
            group.type = Item.GROUP;
            group.text = c + "";
            items.add(group);

            for (int j = 0; j < contacts.size(); j++) {
                Contact contact = contacts.get(j);
                String s = contact.firstLetterOfName();
                if (s.equals(group.text)) {
                    Item child = new Item();
                    child.type = Item.CHILD;
                    child.text = contact.name + "  " + contact.getPhoneNumbers();
                    child.contact = contact;
                    items.add(child);
                }
            }
        }

        PinnedSectionListView listView = (PinnedSectionListView) findViewById(R.id.listView);

        ArrayAdapter<Item> adapter = new MyAdapter(this, -1, items);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Item item = items.get(position);

                if (item.type == Item.CHILD) {
                    Contact contact = item.contact;
                    // 简单演示期间,我们只选择第一个电话(不管有几个电话)。
                    String number = contact.phoneNumbers.get(0);
                    if (!number.equals("")) {
                        // 拨打电话
                        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
                        startActivity(intent);
                    }
                }
            }
        });

    }

    private class MyAdapter extends ArrayAdapter<Item>implements PinnedSectionListAdapter {

        private LayoutInflater inflater;
        private ArrayList<Item> items;

        public MyAdapter(Context context, int resource, ArrayList<Item> items) {
            super(context, resource, items);
            this.items = items;
            inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return items.size();
        }

        @Override
        public int getItemViewType(int position) {

            return items.get(position).type;
        }

        @Override
        public int getViewTypeCount() {

            return 2;
        }

        @Override
        public Item getItem(int position) {
            return items.get(position);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            String text = getItem(position).text;

            switch (getItemViewType(position)) {
            case Item.GROUP:

                if (convertView == null) {
                    convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
                }

                TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);

                // 首字符,分组的依据
                text1.setText(text);
                text1.setBackgroundColor(Color.GRAY);

                break;

            case Item.CHILD:
                if (convertView == null) {
                    convertView = inflater.inflate(android.R.layout.simple_list_item_2, null);
                }

                TextView text2 = (TextView) convertView.findViewById(android.R.id.text2);
                text2.setText(text);

                break;
            }
            return convertView;
        }

        // 假设此方法返回皆为false。那么PinnedSectionListView将退化成为一个基础的ListView.
        // 只不过退化后的ListView只是一个拥有两个View Type的ListView。
        // 从某种角度上讲,此方法对于PinnedSectionListView至关重要,因为返回值true或false,
        // 将直接导致PinnedSectionListView是一个PinnedSectionListView,还是一个普通的ListView。
        @Override
        public boolean isItemViewTypePinned(int viewType) {
            boolean type = false;
            switch (viewType) {
            case Item.GROUP:
                type = true;
                break;

            case Item.CHILD:
                type = false;
                break;

            default:
                type = false;
                break;
            }
            return type;
        }

    }

    // 读取设备联系人的一般方法。大致流程就是这样,模板化的操作代码。
    private void readContacts(ArrayList<Contact> contacts) {
        Uri uri = Uri.parse("content://com.android.contacts/contacts");
        ContentResolver resolver = this.getContentResolver();

        // 在这里我们给query传递进去一个SORT_KEY_PRIMARY
        // 告诉ContentResolver获得的结果按照联系人名字的首字母有序排序
        Cursor cursor = resolver.query(uri, null, null, null,
                android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY);

        while (cursor.moveToNext()) {
            // 联系人id
            String id = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
            // Sort key,读取的联系人按照姓名从 A->Z 的排序分组
            String sork_key_primary = cursor
                    .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY));
            // 获取联系人姓名
            String name = cursor
                    .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));

            Contact mContact = new Contact();
            mContact.id = id;
            mContact.sort_key_primay = sork_key_primary;
            mContact.name = name;

            // 获取联系人的手机号码
            Cursor phone = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id, null, null);
            // 取得电话号码(可能存在多个号码)
            // 因为在同一个名字下,用户可能存有一个以上号码
            // 遍历
            ArrayList<String> phoneNumbers = new ArrayList<String>();
            while (phone.moveToNext()) {
                int phoneFieldColumnIndex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                String phoneNumber = phone.getString(phoneFieldColumnIndex);
                phoneNumbers.add(phoneNumber);
            }

            mContact.phoneNumbers = phoneNumbers;
            contacts.add(mContact);
        }
    }

    // 用于承载数据块的类。
    // 字段分为类型(type)和值(text)。
    private class Item {
        public static final int GROUP = 0;
        public static final int CHILD = 1;

        public int type;
        public String text;

        public Contact contact = null;
    }

    // 用于装载从联系人数据库中读取到的数据。
    // 结构化数据,便于数据操作和访问。
    private class Contact {
        public String id;
        public String name;
        public String sort_key_primay;
        public ArrayList<String> phoneNumbers;

        // 获得一个联系人名字的首字母。
        // 比如一个人的名字叫做“安卓”,那么这个人的首字母是:A
        public String firstLetterOfName() {
            String s = sort_key_primay.charAt(0) + "";

            return s.toUpperCase();
        }

        public String getPhoneNumbers() {
            String phones = "";
            for (int i = 0; i < phoneNumbers.size(); i++) {
                phones += ":     " + phoneNumbers.get(i);
            }
            return phones;
        }
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值