使用Contacts Contract Content Provider操作通讯录最佳实践
Android向所有被赋予READ_CONTACTS权限的应用程序提供了联系人信息数据库的完全访问权限。Contacts Contract使用3层数据模型去存储数据,下面介绍Contacts Contract的子类:
1.Data 表中的每行都定义了个人的数据集(电话号码,email地址,等等),用MIME类型区分开。尽管有为每个个人数据的类型预定义可用的列名(ContactsContract.CommonDataKinds里装有合适的MIME类型),此表能被用来存储任何值。
当向Data表中加入数据的时候,你需要指定与数据集相关的Raw Contact。
2.RawContacts 从Android 2.0(API 5)向前,用户可以增加多个联系人账户的Provider。RawContacts表中的每行定义了一个与数据集相关的账户。说白了就是账户信息。
3.Contacts Contacts表的行聚合了RawContacts中的数据,每行代表了不同的人信息。
读取联系人详情:
首先在庆典文件中添加权限:<uses-permission android:name=”android.permission.READ_CONTACTS”/>
然后是访问Contacts Contract Content Provider:
private String[] getNames() {
/**
* Listing 8-36: Accessing the Contacts Contract Contact Content Provider
*/
// Create a projection that limits the result Cursor
// to the required columns.
String[] projection = {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME
};
// Get a Cursor over the Contacts Provider.
Cursor cursor =
getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
projection, null, null, null);
// Get the index of the columns.
int nameIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int idIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
// Initialize the result set.
String[] result = new String[cursor.getCount()];
// Iterate over the result Cursor.
while(cursor.moveToNext()) {
// Extract the name.
String name = cursor.getString(nameIdx);
// Extract the unique ID.
String id = cursor.getString(idIdx);
result[cursor.getPosition()] = name + " (" + id + ")";
}
// Close the Cursor.
cursor.close();
//
return result;
}
找到联系人姓名的联系信息:
private String[] getNameAndNumber() {
/**
* Listing 8-37: Finding contact details for a contact name
*/
ContentResolver cr = getContentResolver();
String[] result = null;
// Find a contact using a partial name match
String searchName = "andy";
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,
searchName);
// Create a projection of the required column names.
String[] projection = new String[] {
ContactsContract.Contacts._ID
};
// Get a Cursor that will return the ID(s) of the matched name.
Cursor idCursor = cr.query(lookupUri,
projection, null, null, null);
// Extract the first matching ID if it exists.
String id = null;
if (idCursor.moveToFirst()) {
int idIdx =
idCursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
id = idCursor.getString(idIdx);
}
// Close that Cursor.
idCursor.close();
// Create a new Cursor searching for the data associated with the returned Contact ID.
if (id != null) {
// Return all the PHONE data for the contact.
String where = ContactsContract.Data.CONTACT_ID +
" = " + id + " AND " +
ContactsContract.Data.MIMETYPE + " = '" +
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE +
"'";
projection = new String[] {
ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
Cursor dataCursor =
getContentResolver().query(ContactsContract.Data.CONTENT_URI,
projection, where, null, null);
// Get the indexes of the required columns.
int nameIdx =
dataCursor.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME);
int phoneIdx =
dataCursor.getColumnIndexOrThrow(
ContactsContract.CommonDataKinds.Phone.NUMBER);
result = new String[dataCursor.getCount()];
while(dataCursor.moveToNext()) {
// Extract the name.
String name = dataCursor.getString(nameIdx);
// Extract the phone number.
String number = dataCursor.getString(phoneIdx);
result[dataCursor.getPosition()] = name + " (" + number + ")";
}
dataCursor.close();
}
return result;
}
Contacts子类还提供了电话号码查找URI,用来帮助找到与特定电话号码相关的联系人,执行呼叫者ID查找:
private String performCallerId() {
/**
* Listing 8-38: Performing a caller-ID lookup
*/
String incomingNumber = "(650)253-0000";
String result = "Not Found";
Uri lookupUri =
Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
incomingNumber);
String[] projection = new String[] {
ContactsContract.Contacts.DISPLAY_NAME
};
Cursor cursor = getContentResolver().query(lookupUri,
projection, null, null, null);
if (cursor.moveToFirst()) {
int nameIdx =
cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
result = cursor.getString(nameIdx);
}
cursor.close();
return result;
}
使用Intent创建和选择联系人,这是一种最佳的实践做法,其优势在于用户在执行相同任务的时候看到的一致的界面,这可以避免用户感到混淆,并且改善用户体验,下面是悬着一个联系人:
private static int PICK_CONTACT = 0;
private void pickContact() {
Intent intent = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
当选择好之后,作为返回Intent的data属性内的URI返回:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == PICK_CONTACT) && (resultCode == RESULT_OK)) {
resultTextView.setText(data.getData().toString());
}
}
插入新联系人:,当然这需要一个权限:
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
之后就可以插入联系人啦!
Intent intent =
new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT,
ContactsContract.Contacts.CONTENT_URI);
intent.setData(Uri.parse("tel:(650)253-0000")); intent.putExtra(ContactsContract.Intents.Insert.COMPANY, "Google");
intent.putExtra(ContactsContract.Intents.Insert.POSTAL,
"1600 Amphitheatre Parkway, Mountain View, California"); startActivity(intent);
使用Contacts Contract Content Provider操作通讯录最佳实践的更多相关文章
- 我的Android 4 学习系列之数据库和Content Provider
目录 创建数据库和使用SQLite 使用Content Provider.Cusor和Content Value来存储.共享和使用应用程序数据 使用Cursor Loader异步查询Content P ...
- Android Contacts (android通讯录读取)-content provider
Content Provider 在数据处理中,Android通常使用Content Provider的方式.Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据 ...
- Android开发-API指南-Content Provider基础
Content Provider Basics 英文原文:http://developer.android.com/guide/topics/providers/content-provider-ba ...
- Content Provider Basics ——Content Provider基础
A content provider manages access to a central repository of data. A provider is part of an Android ...
- Android Content Provider简介
Content Provider是Android的四大组件之一,与Activity和Service相同,使用之前需要注册: Android系统中存在大量的应用,当不同的应用程序之间需要共享数据时,可以 ...
- Android学习总结——Content Provider
原文地址:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Content Provider内容提供者 : and ...
- Android开发学习之路--Content Provider之初体验
天气说变就变,马上又变冷了,还好空气不错,阳光也不错,早起上班的车上的人也不多,公司来的同事和昨天一样一样的,可能明天会多一些吧,那就再来学习android吧.学了两个android的组件,这里学习下 ...
- 第八章:四大组件之Content Provider
前言 Content Provider——Android四大组件之一. 本文要点 1.Content Provider简介 2.URI简介 3.如何访问Content Provider中数据 一.Co ...
- Android四个基本组件(2)之Service 服务与Content Provider内容提供商
一.Service 维修: 一Service 这是一个长期的生命周期,没有真正的用户界面程序,它可以被用于开发如监视类别节目. 表中播放歌曲的媒体播放器.在一个媒体播放器的应用中.应该会有多个acti ...
随机推荐
- 实验吧_简单的sql注入_1、2、3
简单的sql注入1 看着这个简单的界面,一时间没有特别好的思路,先输入一个1',发生了报错 初步猜测这是一个字符型的注入,他将我们输入的语句直接当成sql语句执行了,按题目的意思后面肯定过滤了很多注入 ...
- [HNOI 2017]影魔
Description 题库链接 给你一段长度为 \(n\) 的序列 \(K\) . \(m\) 组询问,每次给定左右端点 \(l,r\) .求出满足区间内下述贡献和. 如果一个区间的两个端点是这一个 ...
- 【BZOJ4003】【JLOI2015】城池攻占
Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池.这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖,其 ...
- 注意类型转换——Effective C++
注意类型转换: C++提供了四种新式类型转换: const_cast<T>(expression); static_cast<T>(expression); dynamic_c ...
- ●洛谷P3168 [CQOI2015]任务查询系统
题链: https://www.luogu.org/problemnew/show/P3168题解: 主席树 强制在线? 那就直接对每一个前缀时间建一个线段树(可持久化线段树),线段树维护优先度权值. ...
- [SDOI2009]Bill的挑战
题目描述 题解: 因为要求的T长度一定,可定义f[i][j] 为前i位状态为j的方案,can[i][j]表示第i为字母j,可行的状态 每次往后推就行了 #include <algorithm&g ...
- bzoj2127
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 2492 Solved: 1205[Submit][Status][D ...
- django rest-framework 1.序列化 一
上图为项目完整的目录结构 一.入门 需要先安装需要使用到包 pip install django pip install djangorestframework 先来创建一个新项目 django-ad ...
- Python中模块之copy的功能介绍
模块之copy的功能介绍 copy主要分两种: 1.浅拷贝 2.深拷贝 赋值: 在python中赋值算特殊的拷贝,其实赋值可以理解为同一个对象有两个名字,所以当其中一个发生变化,另一个也跟着会变化. ...
- python2.7练习小例子(三)
3):题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 程序分析:假设该数为 x.1.则:x + 100 = n2, x + 100 + ...