基于PinnedSectionListView实现联系人通讯录并且点击打电话
2015-12-24 10:37
232 查看
<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; } } }
相关文章推荐
- iOS开发60- git常用命令
- Mac下配置Cocos2d-x3.1环境
- 版本控制系统相关知识
- Excel VBA保护工作表
- Java 如何有效地避免OOM:善于利用软引用和弱引用
- iOS9项目打包上线
- Python使用面向对象方式创建线程实现12306售票系统
- LD_LIBRARY_PATH 的使用
- c#数据库存取图片的方式
- 根据联系人姓名首字符顺序读取通讯录
- AFNetworking(3.0+)
- Spring auto wire(自动装配) 的 五种方式
- HDU 1241 :Oil Deposits
- 字典Dictionary
- proguardgui.bat来混淆已有的jar包
- 关于一个每日定时推送本地通知的问题
- 链表反转
- 如何在 Ubuntu 中安装最新的 Arduino IDE 1.6.6
- LeetCode 223:Rectangle Area
- 第二章:流程控制与数组