当前位置: 代码迷 >> Android >> 基于PinnedSectionListView实现联系人通讯录而且点击打电话
  详细解决方案

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

热度:24   发布时间:2016-04-27 22:05:00.0
基于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         @Override104         public int getItemViewType(int position) {105 106             return items.get(position).type;107         }108 109         @Override110         public int getViewTypeCount() {111 112             return 2;113         }114 115         @Override116         public Item getItem(int position) {117             return items.get(position);118         }119 120         @Override121         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         @Override158         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_PRIMARY184         // 告诉ContentResolver获得的结果按照联系人名字的首字母有序排序185         Cursor cursor = resolver.query(uri, null, null, null,186                 android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY);187 188         while (cursor.moveToNext()) {189             // 联系人id190             String id = cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));191             // Sort key,读取的联系人按照姓名从 A->Z 的排序分组192             String sork_key_primary = cursor193                     .getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.SORT_KEY_PRIMARY));194             // 获取联系人姓名195             String name = cursor196                     .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         // 比如一个人的名字叫做“安卓”,那么这个人的首字母是:A243         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 }

 

  相关解决方案