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

PinnedSectionListView具体下载地址、使用方法和注意事项:http://www.cnblogs.com/zzw1994/p/4997601.html

怎么根据联系人姓名首字符顺序读取联系人:http://www.cnblogs.com/zzw1994/p/4998524.html

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5      >
 6
 7     <com.zzw.contacts.PinnedSectionListView
 8         android:id="@+id/listView"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent" />
11
12 </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" />

主要实现代码:

  1 package com.zzw.contacts;
  2
  3 import java.util.ArrayList;
  4
  5 import com.zzw.contacts.PinnedSectionListView.PinnedSectionListAdapter;
  6
  7 import android.app.Activity;
  8 import android.content.ContentResolver;
  9 import android.content.Context;
 10 import android.content.Intent;
 11 import android.database.Cursor;
 12 import android.graphics.Color;
 13 import android.net.Uri;
 14 import android.os.Bundle;
 15 import android.provider.ContactsContract;
 16 import android.view.LayoutInflater;
 17 import android.view.View;
 18 import android.view.ViewGroup;
 19 import android.widget.AdapterView;
 20 import android.widget.AdapterView.OnItemClickListener;
 21 import android.widget.ArrayAdapter;
 22 import android.widget.TextView;
 23
 24 public class MainActivity extends Activity {
 25
 26     @Override
 27     protected void onCreate(Bundle savedInstanceState) {
 28         super.onCreate(savedInstanceState);
 29         setContentView(R.layout.activity_main);
 30
 31         ArrayList<Contact> contacts = new ArrayList<Contact>();
 32         readContacts(contacts);
 33
 34         final ArrayList<Item> items = new ArrayList<Item>();
 35
 36         // 从字母A开始到Z。26个字母,遍历联系人中的首字符是否相等。
 37         // 相等则归入一组。
 38         int A = (int) ‘A‘;
 39         for (int i = 0; i < 26; i++) {
 40             int letter = A + i;
 41             char c = (char) letter;
 42
 43             Item group = new Item();
 44             group.type = Item.GROUP;
 45             group.text = c + "";
 46             items.add(group);
 47
 48             for (int j = 0; j < contacts.size(); j++) {
 49                 Contact contact = contacts.get(j);
 50                 String s = contact.firstLetterOfName();
 51                 if (s.equals(group.text)) {
 52                     Item child = new Item();
 53                     child.type = Item.CHILD;
 54                     child.text = contact.name + "  " + contact.getPhoneNumbers();
 55                     child.contact = contact;
 56                     items.add(child);
 57                 }
 58             }
 59         }
 60
 61         PinnedSectionListView listView = (PinnedSectionListView) findViewById(R.id.listView);
 62
 63         ArrayAdapter<Item> adapter = new MyAdapter(this, -1, items);
 64         listView.setAdapter(adapter);
 65
 66         listView.setOnItemClickListener(new OnItemClickListener() {
 67
 68             @Override
 69             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
 70                 Item item = items.get(position);
 71
 72                 if (item.type == Item.CHILD) {
 73                     Contact contact = item.contact;
 74                     // 简单演示期间,我们只选择第一个电话(不管有几个电话)。
 75                     String number = contact.phoneNumbers.get(0);
 76                     if (!number.equals("")) {
 77                         // 拨打电话
 78                         Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
 79                         startActivity(intent);
 80                     }
 81                 }
 82             }
 83         });
 84
 85     }
 86
 87     private class MyAdapter extends ArrayAdapter<Item>implements PinnedSectionListAdapter {
 88
 89         private LayoutInflater inflater;
 90         private ArrayList<Item> items;
 91
 92         public MyAdapter(Context context, int resource, ArrayList<Item> items) {
 93             super(context, resource, items);
 94             this.items = items;
 95             inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 96         }
 97
 98         @Override
 99         public int getCount() {
100             return items.size();
101         }
102
103         @Override
104         public int getItemViewType(int position) {
105
106             return items.get(position).type;
107         }
108
109         @Override
110         public int getViewTypeCount() {
111
112             return 2;
113         }
114
115         @Override
116         public Item getItem(int position) {
117             return items.get(position);
118         }
119
120         @Override
121         public View getView(int position, View convertView, ViewGroup parent) {
122
123             String text = getItem(position).text;
124
125             switch (getItemViewType(position)) {
126             case Item.GROUP:
127
128                 if (convertView == null) {
129                     convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
130                 }
131
132                 TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
133
134                 // 首字符,分组的依据
135                 text1.setText(text);
136                 text1.setBackgroundColor(Color.GRAY);
137
138                 break;
139
140             case Item.CHILD:
141                 if (convertView == null) {
142                     convertView = inflater.inflate(android.R.layout.simple_list_item_2, null);
143                 }
144
145                 TextView text2 = (TextView) convertView.findViewById(android.R.id.text2);
146                 text2.setText(text);
147
148                 break;
149             }
150             return convertView;
151         }
152
153         // 假设此方法返回皆为false。那么PinnedSectionListView将退化成为一个基础的ListView.
154         // 只不过退化后的ListView只是一个拥有两个View Type的ListView。
155         // 从某种角度上讲,此方法对于PinnedSectionListView至关重要,因为返回值true或false,
156         // 将直接导致PinnedSectionListView是一个PinnedSectionListView,还是一个普通的ListView。
157         @Override
158         public boolean isItemViewTypePinned(int viewType) {
159             boolean type = false;
160             switch (viewType) {
161             case Item.GROUP:
162                 type = true;
163                 break;
164
165             case Item.CHILD:
166                 type = false;
167                 break;
168
169             default:
170                 type = false;
171                 break;
172             }
173             return type;
174         }
175
176     }
177
178     // 读取设备联系人的一般方法。大致流程就是这样,模板化的操作代码。
179     private void readContacts(ArrayList<Contact> contacts) {
180         Uri uri = Uri.parse("content://com.android.contacts/contacts");
181         ContentResolver resolver = this.getContentResolver();
182
183         // 在这里我们给query传递进去一个SORT_KEY_PRIMARY
184         // 告诉ContentResolver获得的结果按照联系人名字的首字母有序排序
185         Cursor cursor = resolver.query(uri, null, null, null,
186                 android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY);
187
188         while (cursor.moveToNext()) {
189             // 联系人id
190             String id = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));
191             // Sort key,读取的联系人按照姓名从 A->Z 的排序分组
192             String sork_key_primary = cursor
193                     .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY));
194             // 获取联系人姓名
195             String name = cursor
196                     .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));
197
198             Contact mContact = new Contact();
199             mContact.id = id;
200             mContact.sort_key_primay = sork_key_primary;
201             mContact.name = name;
202
203             // 获取联系人的手机号码
204             Cursor phone = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
205                     ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id, null, null);
206             // 取得电话号码(可能存在多个号码)
207             // 因为在同一个名字下,用户可能存有一个以上号码
208             // 遍历
209             ArrayList<String> phoneNumbers = new ArrayList<String>();
210             while (phone.moveToNext()) {
211                 int phoneFieldColumnIndex = phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
212                 String phoneNumber = phone.getString(phoneFieldColumnIndex);
213                 phoneNumbers.add(phoneNumber);
214             }
215
216             mContact.phoneNumbers = phoneNumbers;
217             contacts.add(mContact);
218         }
219     }
220
221     // 用于承载数据块的类。
222     // 字段分为类型(type)和值(text)。
223     private class Item {
224         public static final int GROUP = 0;
225         public static final int CHILD = 1;
226
227         public int type;
228         public String text;
229
230         public Contact contact = null;
231     }
232
233     // 用于装载从联系人数据库中读取到的数据。
234     // 结构化数据,便于数据操作和访问。
235     private class Contact {
236         public String id;
237         public String name;
238         public String sort_key_primay;
239         public ArrayList<String> phoneNumbers;
240
241         // 获得一个联系人名字的首字母。
242         // 比如一个人的名字叫做“安卓”,那么这个人的首字母是:A
243         public String firstLetterOfName() {
244             String s = sort_key_primay.charAt(0) + "";
245
246             return s.toUpperCase();
247         }
248
249         public String getPhoneNumbers() {
250             String phones = "";
251             for (int i = 0; i < phoneNumbers.size(); i++) {
252                 phones += ":     " + phoneNumbers.get(i);
253             }
254             return phones;
255         }
256     }
257 }
时间: 2024-09-30 20:55:22

基于PinnedSectionListView实现联系人通讯录并且点击打电话的相关文章

Android基于PinnedSectionListView实现联系人通讯录

 <Android基于PinnedSectionListView实现联系人通讯录> 我在之前的文章中写过文章,介绍过PinnedSectionListView(文章地址链接: http://blog.csdn.net/zhangphil/article/details/47144125 )[文1],也有一篇文章是关于Android通讯录联系人操作的基础知识(文章地址链接: http://blog.csdn.net/zhangphil/article/details/47250747 )[文

【WP8.1开发】基于应用的联系人存储

上一篇文章所吹的牛是访问系统(手机)上的联系人,当然那只是读不能改,这是自然的,要是让你能随便修改用户的联系人信息的话,那后果很严重,有些恶意开发者就有可能把”你的户口改成猪“. 但是,API也允许应用程序读写自己的联系人信息,即系统会为某个应用程序分配一个联系人存储区,应用程序可以在其中读写联系人信息.基于应用的联系人存储会集成到系统的”人脉“应用中,也就是说你保存到属于你的应用的联系人会显示在”人脉“应用中. 用于读写基于应用的联系人的API都位于Windows.Phone.Personal

超实用python小项目--基于python的手机通讯录二维码生成网站--1、项目介绍和开发环境

这个项目是我做完整的第一个python web项目,对于新手来说,这个项目绝对是一个特别好的练手项目. 起名还是困难,但是自己确实比较烦输入这么长的名字(手机通讯录二维码生成网站)去定义这个网站,所以还是给这个项目起个名字吧,叫什么呢?就叫 "鹅日通讯录"吧(Earth address list). --------------------------------------------------------------------------------------------我是

解析、查找数组中重复出现的元素(Java)

 解析.查找数组中重复出现的元素,Java实现. <数据结构与算法分析:解析.查找数组中重复出现的元素> 问题描述:一个结构化数据,假设事先按照某种顺序排好序(比如升序)的一个数组中,无规则.重复出现若干次某个相同元素,形如有序数组data: data = {  "A", "A", "B", "C", "C", "D", "D" , "D&q

物联网开发入门+项目实战视频博学全套

物联网开发入门+项目实战视频博学全套物联网网络编程项目实战视频课程以目前在物联网中比较热门的技术平台为依据,实操为主,理论讲解为辅;引导学员...适用人群对物联网通讯感兴趣的技术人员或在校工科类学生:具备一点C语言基础.课程简介物联网网络编程项目实战视频课程以目前在物联网中比较热门的技术平台为依据,实操为主,理论讲解为辅:引导学员去进行一些简单项目的开发和练习,尽可能通俗的讲解物联网所涉及到的协议.课程大致目录:第1阶段 学前准备01 C语言及程序设计快速入门02 嵌入式C语言高级---语法概述

Swift - 访问通讯录联系人(使用系统提供的通讯录交互界面)

1,通讯录访问介绍 通讯录(或叫地址簿,电话簿)是一个数据库,里面储存了联系人的相关信息.要实现访问通讯录有如下两种方式: (1)AddressBook.framework框架 : 没有界面,通过代码来获取所有联系人信息 (2)AddressBookUI.framework框架 : 通过系统提供的通讯录交互界面来访问(本文样例使用此方式) 2,联系人记录的属性 在一条联系人记录中,有很多属性,而这些属性又分为单值属性和多值属性. 单值属性是只有一个值的属性:如姓氏.名字.部门.备注等. 多值属性

Android6.0运行时权限(基于RxPermission开源库)

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了. Android 6.0 采用新的权限模型,只有在需要权限的时候,才告知用户是否授权:是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请. 判断是否是需要运行时权限的标记就是targetSDKVersion. 当targetSDKVersi

【Android】利用AutoCompleteTextView控件联系人自动补全与根据联系人姓名查询电话

自动补全功能是app比较友好的功能之一,但利用AutoCompleteTextView自动补全文本框控件完成起来并不简单,因为其中涉及到AutoCompleteTextView填充数据的适配器,与AutoCompleteTextView的监听器.同时还需要利用ContentResolver去查找设备的通讯录,当然,这与<[Android]利用安卓的数据接口.多媒体处理编写内存卡Mp3播放器app>(点击打开链接)中遍历MP3与<[Android]Sqlite数据库增删改查>(点击打

基于JavaBean的在线日常事务管理系统

获取项目源文件,技术交流与指导联系Q:1225467431 [摘要] 随着计算机技术的飞速发展,计算机技术在信息管理中的应用也越来越普及.人们可以脱离传统的记事本,通讯录,越来越多的靠计算机来帮助人们完成这些功能,非常的快捷方便.所以使用计算机来实现记事本,通讯录以及类似的其他功能也是大势所趋的.本系统是一个在线的日常事务管理系统,采用J2EE,JavaBean,Jsp,MySql等技术来实现.系统包括了记事本,通讯录,资源的上传下载,收藏夹这几个主要功能,还有用户登录以及后台管理的辅助功能,界