-----------------
通讯录列表
-----------------
按常理来说,获取系统通讯录列表,无非就是将通讯录的数据库打开获取数据,适配,添加即可。
Cursor cursor; HashMap<Integer, ContactBean> contactIdMap = new HashMap<Integer, ContactBean>(); ArrayList<ContactBean> list = new ArrayList<ContactBean>(); cursor.moveToFirst();// 游标移动到第一项 for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); String name = cursor.getString(1); String number = cursor.getString(2); String sortKey = cursor.getString(3); int contactId = cursor.getInt(4); Long photoId = cursor.getLong(5); String lookUpKey = cursor.getString(6); if (contactIdMap.containsKey(contactId)) { // 无操作 } else { // 创建联系人对象 ContactBean contact = new ContactBean();// 实例化一个联系人 contact.setDesplayName(name);// 设置联系人的名字为name contact.setPhoneNum(number);// 设置联系人的电话号为number contact.setSortKey(sortKey);// 设置联系人的分类键 contact.setPhotoId(photoId);// 设置联系人的照片id contact.setLookUpKey(lookUpKey);// 设置联系人的 list.add(contact);// 将该加工好的联系人放入list列表中 contactIdMap.put(contactId, contact); // 通讯录中的Map集合众放入该联系人id和该联系人对象 } } // 如果list中有东西,就将list数据放入到适配器中 if (list.size() > 0) { //进行数据适配。。。。。。 }
然后,通过mvc原则:listView+data+adapter = 列表
ListView contactList; ContactListAdapter adapter = new ContactListAdapter(this); // 实例化一个侧边栏中快速搜索条适配器对象 contactList.setAdapter(adapter);
然而,我们发现,系统通讯录中提供的不仅仅是联系人的姓名,电话,还有其首字母,那么我们更希望,能做出通过首字母的选择去快速搜索联系人了。
怎么做?
1.首先获取首字母,这个在获取系统通讯录基本信息时就有了。sortKey
2.系统的通讯录数据库的帮助类:AsyncQueryHandler.java
系统是以姓名作为唯一标示,如果 系统存在 (习,10086,李 10000,王 10010,习 110) 这几个联系人。在系统通讯录下是3个,因为系统会自动合并
在QQ通讯录,360通讯录,百度通讯录都是3个,而且我们通过ContactsContract.Contacts.CONTENT_URI也是3个,
但是通过Phone查询是4个,通过RawContact查询的是4个,通过Phone和RawContact查询的是联系人的详细信息,是有电话号码的,但是通 过ContactsContract.Contacts.CONTENT_URI是没有电话号码的,所以我们为了提高效率,必须考虑是否查询Phone这个url
简单系统数据库字典
命名 | 类型 | 获取值 | 别名 |
contactId | Int | cursor.getInt(4) ContactsContract.CommonDataKinds.Phone._ID | 联系人id |
displayName | String | cursor.getString(1) ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME | 显示名,即姓名 |
phoneNum | String | cursor.getString(2) ContactsContract.CommonDataKinds.Phone.CONTACT_ID | 电话号码 |
sortKey | String | cursor.getString(3) ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key" | 分类键 |
photoId | Long | cursor.getLong(5) ContactsContract.CommonDataKinds.Phone.PHOTO_ID | 照片头像 |
lookUpKey | String | cursor.getString(6) ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY | lookUpKey |
formattedNumber | String |
|
|
pinyin | String |
| 姓名的中文拼音 |
selected | Int |
| 被选项 |
2.创建快速索引条
a) 布局中
<com.slifeassistant.utils.QuickAlphabeticBar android:id="@+id/fast_scroller" android:layout_width="22dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_gravity="top|right|center" android:layout_marginTop="0dip" android:background="@null" android:scaleType="centerInside" android:src="@drawable/dic_background" > </com.slifeassistant.utils.QuickAlphabeticBar> <TextView android:id="@+id/fast_position" android:layout_width="70dip" android:layout_height="70dip" android:layout_centerInParent="true" android:layout_gravity="center_horizontal|top" android:layout_margin="34dip" android:background="@drawable/sort_icon_bg_click" android:gravity="center" android:padding="2dip" android:textColor="@color/white" android:textSize="48dip" android:visibility="invisible" />
a) QuickAlphabeticBar是一个自定义view
2.如果通过首字母去获取快速搜索,就要将所有数据进行分类存储
a) 通过获取字母表中首字母的值,将数据按字母分为各个小集合
private HashMap<String, Integer> alphaIndexer; // 字母索引 private String[] sections;// 存储每个章节 Set<String> sectionLetters = alphaIndexer.keySet();// 获取字母表中的首字母 ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);// 将首字母放到ArrayList的集合中 Collections.sort(sectionList);//集合分类列表 sections = new String[sectionList.size()];//新建一个 sectionList.toArray(sections);
a) 在定义适配器的时候,如果所选侧边栏字母等于列表首字母,就刷新该首字母的小集合进行数据适配。并对UI进行设计
// 侧边栏当前字母 String currentStr = getAlpha(contact.getSortKey()); // 列表当前首字母 String previewStr = (position - 1) >= 0 ? getAlpha(list.get( position - 1).getSortKey()) : " "; if (!previewStr.equals(currentStr)) { holder.alpha.setVisibility(View.VISIBLE); holder.alpha.setText(currentStr); } else { holder.alpha.setVisibility(View.GONE); }
a) 设置放入适配器的方法,其中包含自定义view的显示
// 定义设置放入适配器的方法 通讯录类型的列表 list private void setAdapter(List<ContactBean> list) { adapter = new ContactListAdapter(this, list, alphabeticBar); // 实例化一个侧边栏中快速搜索条适配器对象 contactList.setAdapter(adapter); // 将该适配器放入通讯录listview控件中 alphabeticBar.init(ContactListActivity.this); // 将alphabeticBar中德init方法初始化 在中间显示的分类 alphabeticBar.setListView(contactList); alphabeticBar.setHight(alphabeticBar.getHeight()); alphabeticBar.setVisibility(View.VISIBLE); }
2.点击拨打
if (num != null) { Intent intent = new Intent("android.intent.action.CALL", Uri.parse("tel:" + num)); startActivity(intent); }
2.最后是将系统数据存到String数组中,方便用
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;// 联系人uri // 查询的字段 String[] projection = { ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key", ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.PHOTO_ID, ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY };
-----------------
通话记录
----------------
简单系统数据库字典
命名 | 类型 | 获取值 | 别名 |
id | Int | CallLog.Calls._ID | Id值 |
name | String | CallLog.Calls.CACHED_NAME | 名称
|
number | String | CallLog.Calls.NUMBER | 号码 |
date | String | CallLog.Calls.DATE | 日期
|
type | Int | CallLog.Calls.TYPE | 来电:1,拨出:2,未接:3
|
count | Int |
|
通话次数 |
数据初始化
Uri uri = android.provider.CallLog.Calls.CONTENT_URI; // 查询的列 String[] projection = { CallLog.Calls.DATE, // 日期 CallLog.Calls.NUMBER, // 号码 CallLog.Calls.TYPE, // 类型 CallLog.Calls.CACHED_NAME, // 名字 CallLog.Calls._ID, // id }; asyncQuery.startQuery(0, null, uri, projection, null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
---------------
短信记录
---------------
简单系统数据库字典
命名 | 类型 | 获取值 | 别名 |
id | Int | c.getColumnIndex("_id") | Id |
thread_id | Int | thread_id 1=1) group by(thread_id | 子id |
address | String | c.getColumnIndex("address") | 地址(电话) |
content | String | c.getColumnIndex("body") | 内容 |
type | Int | c.getColumnIndex("type") | 类型 |
date | Long | count(*) as cnt | 时间 |
数据初始化
Cursor c = cr.query(uri, new String[] { "thread_id", "address", "date", "body", "count(*) as cnt" }, "1=1) group by(thread_id", null, "date desc"); if (c != null) { threads = new ArrayList<ThreadInfo>(); while (c.moveToNext()) { ThreadInfo info = new ThreadInfo(); info.setId(c.getInt(c.getColumnIndex("thread_id"))); info.setAddress(c.getString(c.getColumnIndex("address"))); info.setContent(c.getString(c.getColumnIndex("body"))); info.setDate(c.getLong(c.getColumnIndex("date"))); info.setCount(c.getInt(c.getColumnIndex("cnt"))); threads.add(info); } c.close();