这是什么啊

Android15_ContentProvider之ContentResolver

ContentProvider之ContentResolver

短信 sms 
文件 /data/data/com.android.providers.telephony/databases/mmssms.db 
这个数据库有13张表,sms表存了短信信息。

sms表字段       

id                         primary key     integer                  与words表内的source_id关联

thread_id              会话id,一个联系人的会话一个id,与threads表内的_id关联      integer

address                 对方号码          text

person                  联系人id           integer             

date                      发件日期           integer

protocol               通信协议,判断是短信还是彩信     integer       0:SMS_RPOTO, 1:MMS_PROTO

read                      是否阅读           integer       default 0             0:未读, 1:已读  

status                   状态                  integer       default-1           -1:接收,

                                                                                                   0:complete,

                                                                                                  64: pending,

                                                                                                 128: failed 

type                     短信类型           integer                                     1:inbox

                                                                                                    2:sent

                                                                                                    3:draft56

                                                                                                    4:outbox

                                                                                                    5:failed

                                                                                                    6:queued            

body                      内容 

service_center      服务中心号码

subject                  主题 

reply_path_present 

locked

error_code

seen

短信常用uri

content://sms/inbox         收件箱  
content://sms/sent           已发送  
content://sms/draft          草稿  
content://sms/outbox      发件中 
content://sms/failed         失败  
content://sms/queued     待发送

短信数据库所有表及字段:
表4.1 addr(彩信地址)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
msg_id
INTEGER
The ID of MM whcich this 
Address entry belongs to.
Pdu主键关联
contact_id
INTEGER
The ID of contact entry in Phone Book
address
TEXT
The address text
type
INTEGER
Type of address,must be one
Of PduHeaders.BCC, PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO.
charset
INTEGER
Character set of entry

表4.2 android_metadata(语言)
字段名
类型
描述
备注
locale
TEXT
本地采用语言
例如:zh_CN

表4.3 attachments (附件)
字段名
类型
描述
备注
sms_id
INTEGER
短信id
FK,短信表主键
content_url
TEXT
url
offset
INTEGER
偏移量
表4.4 canonical_addresses(所以短信删除,此数据依然存在)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
address
TEXT
发送或接收的电话号码
表4.5 drm()
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
_data
TEXT
处理加密解密的数据
表4.6 part(存储了彩信内容(文本、音乐、图象)的文件名(即在parts下面的文件名)、文件类型信息)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
mid
INTEGER
The identifier of the message which this part belongs to.
Pdu主键关联
seq
INTEGER
The order of the part
所发送Part的顺序
ct
TEXT
The content type of the part
彩信数据类型
name
TEXT
The name of the part
Part名称
chset
INTEGER
The charset of the part.
字符集
cd
TEXT
The content disposition of the part.
内容配置
fn
TEXT
The file name of the part.
文件名称
cid
TEXT
The content ID of the part
cl
TEXT
The content location of the part
ctt_s
INTEGER
The start of content-type of the message
ctt_t
TEXT
The type of content-type of the message
_data
TEXT
The location(on filesystem) of the binary data of the part.
数据的位置
:/data/data/com.providers.telephony/app_parts/PART_1300271462558
这个字段基本没什么用,不能直接读取这个文件,读取同样需要通过ContentProvider,URI为”conteng://mms/part”
text
TEXT
表4.7 pdu(彩信)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
thread_id
INTEGER
Threads 的PK
FK
date
INTEGER
The date the message was sent.
发送日期
read
INTEGER
Has the message been read
已读为1,未读为0
m_id
TEXT
The Message-ID of the message.
sub
TEXT
The subject of the message, if present
主题
sub_cs
INTEGER
The character set of the subject, if present
主题所用字符集
ct_t
TEXT
The Content-Type of the message
ct_l
TEXT
The Content-Location of the message.
exp
INTEGER
The expiry time of the message.
过期时间
m_cls
TEXT
The class of the message.
m_type
INTEGER
The type of the message defined by MMS spec
v
INTEGER
The version of specification that this message conform.
m_size
INTEGER
The size of the message
彩信大小
pri
INTEGER
The priority of the message.
rr
INTEGER
The read-report of the message.
rpt_a
INTEGER
Whether the report is allowed.
resp_st
INTEGER
The response-status of the message.
st
INTEGER
The status of the message.
tr_id
TEXT
The transaction-id of the message.
retr_st
INTEGER
The retrieve-status of the message.
retr_txt
TEXT
The retrieve-text of the message.
retr_txt_cs
INTEGER
The character set of the retrieve-text.
read_status
INTEGER
The read-status of the message.
ct_cls
INTEGER
The content-class of the message.
resp_txt
TEXT
The response-text of the message.
d_tm
INTEGER
The delivery-time of the message.
d_rpt
INTEGER
The delivery-report of the message.
locked
INTEGER
Has the message been locked?
sim_id
INTEGER
seen
INTEGER
Indicates whether this message has been seen by the user. The "seen" flag will be used to figure out whether we need to throw up a statusbar notification or not.
有看为1,否则为0
表4.8 pending_msgs
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
proto_type
INTEGER
The type of transport protocol(MMS or SMS).
msg_id
INTEGER
The ID of the message to be sent or downloaded.
msg_type
INTEGER
The type of the message to be sent or downloaded.             This field is only valid for MM. For SM, its value is always
err_type
INTEGER
The type of the error code.
err_code
INTEGER
The error code of sending/retrieving process.
retry_index
INTEGER
How many times we tried to send or download the message.
due_time
INTEGER
The time to do next retry.
pending_sim_id
INTEGER
last_try
INTEGER
The time we last tried to send or download the message.

表4.9 rate(彩信发送时间)
字段名
类型
描述
备注
sent_time
INTEGER
When a message was successfully sent.

表4.10 raw(This table is used by the SMS dispatcher to hold         incomplete partial messages until all the parts arrive.)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
_data
INTEGER
处理加密解密的数据
reference_number
INTEGER
one per full message
count
INTEGER
the number of parts
sequence
INTEGER
the part number of this message
destination_port
INTEGER
address
TEXT
sim_id
INTEGER
pdu
TEXT
the raw PDU for this part


表4.11 sms(短信)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
thread_id
INTEGER
Threads 的PK
FK
在短信界面里显示在第一组的第一行
address
TEXT
对方短信号码
person
INTEGER
存在电话薄里的名字,不存在的为空
date
INTEGER
日期
protocol
INTEGER
发送短信为空,收到为0
read
INTEGER
已读未读
已读为1,未读为0
status
INTEGER
a TP-Status value or -1 if it status hasn't been received
type
INTEGER
发短信为2,收到短信为1
reply_path_present
INTEGER
发短信为空,收到的为0
subject
TEXT
主题
body
TEXT
短信内容
service_center
TEXT
运营商服务电话
locked
INTEGER
是否锁掉了。
0为未锁,1已锁
sim_id
INTEGER
error_code
INTEGER
The error code of sending/retrieving process.
seen
INTEGER
Indicates whether this message has been seen by the user. The "seen" flag will be used to figure out whether we need to throw up a statusbar notification or not.
有看为1,否则为0


4.12 sr_pending(This table is used by the SMS dispatcher to hold pending delivery status

字段名
类型
描述
备注
reference_number
INTEGER

action
TEXT

data
TEXT


4.13 threads(在ConversationList.java中显示的当前短信)
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
date
INTEGER
The date at which the thread was created.
日期
message_count
INTEGER
The message count of the thread.
短信总条数
recipient_ids
TEXT
canonical_addresses的主键
FK
snippet
TEXT
The snippet of the latest message in the thread.
在最前面显示的短信
snippet_cs
INTEGER
The charset of the snippet.
read
INTEGER
Indicates whether all messages of the thread have been read.
已读为1,未读为0
type
INTEGER
Type of the thread, either Threads.COMMON_THREAD or         Threads.BROADCAST_THREAD.
push的短信为0
error
INTEGER
Indicates whether there is a transmission error in the thread.
有错误为1,没有为0
has_attachment
INTEGER
Indicates whether this thread contains any attachments.
没有为1,有为0

4.15 words
字段名
类型
描述
备注
_id
INTEGER
如果是短信则与source_id相同;如果为彩信则是:
2<<32+source_id

index_text
TEXT
存储的信息内容

source_id
INTEGER
如果是短信则表示sms_id
如果是彩信则表示pdu的_id

table_to_use
INTEGER

短信为1,彩信为2
4.16 words_content
字段名
类型
描述
备注
docid
INTEGER PRIMARY_KEY
主键ID
系统生成
c0_id
INTEGER
如果是短信则与source_id相同;如果为彩信则是:
2<<32+ c2source_id

c1index_text
TEXT
存储的信息内容

c2source_id
INTEGER
如果是短信则表示sms_id
如果是彩信则表示pdu的_id

c3table_to_use
INTEGER

短信为1,彩信为2
4.17 words_segdir
字段名
类型
描述
备注
level
INTEGER PRIMARY_KEY
主键ID

idx
INTEGER PRIMARY_KEY
主键ID

start_block
INTEGER
开始块

leaves_end_block
INTEGER


end_block
INTEGER
结束块

root
BLOB


4.18 word_segments
字段名
类型
描述
备注
blockid
INTEGER PRIMARY_KEY
主键ID
系统生成
block
BLOB




simcontacts.db 中的表相对较少,只有三个:

数据库simcontacts.db中表的定义见表4.19至4.21所示:
表4.19 android_metadata
字段名
类型
描述
备注
locale
TEXT
本地采用语言
例如:zh_CN

表4.20 simPeople
字段名
类型
描述
备注
_id
INTEGER PRIMARY_KEY
主键ID
系统生成
name
TEXT


number
TEXT


simid
INTEGER


email
TEXT


pinyin
TEXT
拼音

表4.21 simPeopleLookup
字段名
类型
描述
备注
token
TEXT


source
INTEGER

与simPeople的_id进行关联
联系人表结构

联系人的主要数据存放在raw_contacts和data表里,它两构成主从表关系。

raw_contacts表结构:

data表结构:

每个联系人在raw_contacts里有一条记录,像地址,名称,email,电话等等数据都在data存放在data里,这样设计的好处是易扩展,比如要增加一个联系人的email地址时,只要在data里增加一条记录。

联系人的数据库比较复杂,在联系人相关应用开发中,一般也不直接通过数据库字段来操作,主要用视图(指定的Uri)来操作。

下面说说我在开发工作中用到的一些联系人的数据。


名字:

Uri: Uri.parse("content://com.android.contacts/data")

PREFIX = "data4"; //名称前缀
MID_NAME = "data5";//中间名
GIVEN_NAME = "data2";//名字
FAMILY_NAME = "data3";//姓氏
MID_PINYIN="data8"; //中间名拼音
String FAMILY_NAME_PINYIN="data9"; //姓氏拼音
String SUFIX = "data6"; //名称后缀
String SUFIX_PINYIN="data7"; //名字拼音


电话:

Uri: Uri.parse("content://com.android.contacts/data/phones"

phone: "data1";//号码

Type: "data2";//这个字段是整形值,指示电话类型

类型对应关系如下:

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_MOBILE = 2;
TYPE_WORK = 3;
TYPE_FAX_WORK = 4;
TYPE_FAX_HOME = 5;
TYPE_PAGER = 6;
TYPE_OTHER = 7;

 

Email:

Uri:Uri.parse("content://com.android.contacts/data/emails")

Email: "data1";//邮箱地址

Type: "data2";//这个字段是整形值,指示Email类型

类型对应关系如下:

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;
TYPE_MOBILE = 4;

 

地址:

Uri:Uri.parse("content://com.android.contacts/data/postals")

STREET="data4";//街道
CITY="data8";//城市
STATE="data7";//州
ZIP_CODE="data9";//邮政编码

Type:"data2";//type的类型如下

TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;

联系人权限设置

 <!-- 读联系人权限 -->

 <uses-permission android:name="android.permission.READ_CONTACTS"/>

 <!-- 写联系人权限 -->

 <uses-permissionandroid:name="android.permission.WRITE_CONTACTS" />


(四)、系统内置的预定义ContentProvider:
1、Contacts:获取、修改、保存联系人的信息;
2、MediaStore:访问声音、视频、图片等多媒体文件;
3、CallLog :查看或更新通话记录;
4、Browser:读取或修改浏览历史、网络搜索、书签;
5、Setting:查看和获取蓝牙设置、铃声设置等设备首选项。
6、SMS:短信
Authority 授权
simpleadapter的刷新:
三、使用ContentResolver 管理联系人:
(一)、 使用ContentResolver 操作数据的步骤
1、调用Context的getContentResolver()方法获得ContentResolver 对象;
2、调用使用ContentResolver 的insert()、delete()、update()、query()方法操作数据。
  • Uri insert(Uri uri, ContentValues values)  返回值是Uri,得到Uri中的数据用 ContentUris.parseId
  • int delete(Uri uri, String where, String[] whereArgs)
  • int update(Uri uri, ContentValues values, String where, String[] whereArgs)    
  • Cursor query(Uri uri, String[] projection, String where, String[] whereArgs, String sortOrder)最后参数 _id desc 表示按id进行排序
参数解释:
String   where:表示带有占位符的where子句组成的字符串;
String[]   whereArgs:表示替换where参数中占位符后的数据组成的字符串数组;
String   sortOrder:表示select语句中的order by子句组成的字符串;
String[]   projection:表示select语句中需要查询的所有的字段组成的字符串数组。
ContentValues values:是由数据库中表字段和往该字段中放置的数据所组成的键值对对象。
【备注:】以上四个方法的参数分别是2、3、4、5个。
读写联系人数据库权限  ReadCONTACTS  WRITE
(二)、 联系人管理中ContentProvider的几个Uri
1、联系人的Uri==>      content://com.android.contacts/contacts 和 content://com.android.contacts/raw_contacts
2、电话号码的Uri==>  content://com.android.contacts/data/phones
3、EMAIL的URI==>     content://com.android.contacts/data/emails
        content://固定前缀
         com.android.contacts叫做Authority 授权
        /contacts  这叫path
simpleCursorAdapter(上下文,布局,数据源,查找字段,放字段的布局id,常量值2)
不过为了方便记忆,系统中提供了以下常量来替代以上的Uri字符串。
  • Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
  • Uri PHONE_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
  • Uri EMAIL_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;

四、系统自带ContentProvider的常用Uri地址:

(一)、Android系统管理联系人的Uri如下:

  1. ContactsContract.Contacts.CONTENT_URI 管理联系人的Uri
  2. ContactsContract.CommonDataKinds.Phone.CONTENT_URI 管理联系人的电话的Uri
  3. ContactsContract.CommonDataKinds.Email.CONTENT_URI 管理联系人的Email的Uri
【数据库中主要字段:】

  1. 联系人id字段名称为:ContactsContract.Contacts._ID
  2. 联系人name 字段为:ContactContract.Contracts.DISPLAY_NAME
  3. 电话信息表的外键id为:ContactsContract.CommonDataKinds.Phone.CONTACT_ID
  4. 电话号码 字段为:ContactsContract.CommonDataKinds.Phone.NUMBER.
  5. Email 字段为:ContactsContract.CommonDataKinds.Email.DATA
  6. 其外键为:ContactsContract.CommonDataKinds.Email.CONTACT_ID


(二)、Android为多媒体提供的ContentProvider的Uri如下:

  1. MediaStore.Audio.Media.EXTERNAL_CONTENT_URI        存储在SD卡上的音频文件
  2. MediaStore.Video.Media.EXTERNAL_CONTENT_URI         存储在 SD卡上的视频
  3. MediaStore.Images.Media.EXTERNAL_CONTENT_URI       存储在 SD卡上的图片文件内容
  4. MediaStore.Audio.Media.INTERNAL_CONTENT_URI         手机内部存储器上的音频文件 
  5. MediaStore.Video.Media.INTERNAL_CONTENT_URI          手机内部存储器上的视频
  6. MediaStore.Images.Media.INTERNAL_CONTENT_URI        手机内部存储器上的图片

图片数据库字段:20个_id,_data,_size,_display_name,mime_type,title,date_added,date_modified,description,picasa_id,isprivate,latitude,longitude,datetaken,orientation,mini_thumb_magic,bucket_id,bucket_display_name,width,height

音频数据字段:29个
_id,_data,_display_name,_size,mime_type,date_added,is_drm,date_modified,title,title_key,duration,artist_id,composer,album_id,track,year,is_ringtone,is_music,is_alarm,is_notification,is_podcast,bookmark,album_artist,artist_id:1,artist_key,artist,album_id:1,album_key,album,

视频数据字段:27个
_id,_data,_display_name,_size,mime_type,date_added,date_modified,title,duration,artist,album,resolution,description,isprivate,tags,category,language,mini_thumb_data,latitude,longitude,datetaken,mini_thumb_magic,bucket_id,bucket_display_name,bookmark,width,height,

【数据库中主要字段:】

  1. 图片名称字段:Media.DISPLAY_NAME
  2. 图片的详细描述字段:Media.DESCRIPTION  
  3. 图片的保存位置字段:Media.DATA

(三)、短信Uri:

  1.  content://sms                所有短信
  2. content://sms/outbox      发送箱中的短信 
  3. content://sms/inbox       收件箱中短信
sms表中主要字段:】

  1. 短信手机号码 : address
  2. 短信标题:  subject
  3. 短信内容:body
  4.  短信发送时间戳:date
  5. 短信类型:type    【0:待发信息; 1:接收到信息; 2:发出】
  6. _id

(四)、通话记录Uri:

  1.  content://call_log/calls               所有通话记录 "_id", "number", "date", "type"

【备注:】URI、URL、URN的区别:
  • 首先,URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
  • URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
  • URN,uniform resource name,统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。
        也就是说,URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。
        总结一下:URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,所以,是绝对的。
(三)、示例代码1——查看通讯录中的联系人姓名、id、电话、Email等信息:

publicstatic List<Map<String, Object>> selectContactsMsg(
ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse(uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);


// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts
.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts
.getColumnIndex("display_name"));


Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);


// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(
Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);


// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());


// 以下开始或许Email信息
Cursor cursor_emails = resolver.query(
Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());


// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}


(四)、示例代码2——实现新添加通讯录信息:

// 以下方法是利用常量值所写的插入联系人的方法。如果希望封装成方法,再增加一个Map集合的参数,用来传入信息即可。
publicvoid insertContacts(ContentValues values, ContentResolver resolver) {
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(
ContactsContract.RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);


// 往data表入姓名数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
values.put(
ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
"王向军");
values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
"王向军");
resolver.insert(ContactsContract.Data.CONTENT_URI, values);


// 往data表入电话数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "13520551441");
values.put(ContactsContract.CommonDataKinds.Phone.TYPE,
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);


// 往data表入Email数据
values.clear();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Email.DATA,
"237235475@qq.com");
values.put(ContactsContract.CommonDataKinds.Email.TYPE,
ContactsContract.CommonDataKinds.Email.TYPE_WORK);
resolver.insert(ContactsContract.Data.CONTENT_URI, values);
}

(五)、封装ContentResolver操作系统联系人的工具类ContactsResolverHelper:【重要】

publicclass ContactsResolverHelper {


/*
* / 以下代码是插入新联系人的子过程。其中第三个参数:List集合表示要插入到通讯录中的新数据(该集合中有三个值,分别是:姓名、电话、email)。
*/
publicvoid insertContacts(ContentResolver resolver, ContentValues values,
List<String> list) {
String uri_rawcontacts = "content://com.android.contacts/raw_contacts";
String uri_data = "content://com.android.contacts/data";
Uri uri = Uri.parse(uri_contacts);
// 首先向RawContacts.CONTENT_URI执行一个空值插入,目的是获取系统返回的rawContactId
Uri rawContactUri = resolver.insert(Uri.parse(uri_rawcontacts), values);
long contact_id = ContentUris.parseId(rawContactUri);


// 往data表中插入一条用户的名称信息
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/name");
values.put("data1", list.get(0));
values.put("data2", list.get(0));
resolver.insert(uri_data, values);


// 往data表中插入电话信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/phone_v2");
values.put("data1", list.get(1));
values.put("data2", 2);// 2,Phone.TYPE_MOBILE ,表示手机号码
resolver.insert(uri_data, values);


// 往data表中插入Email信息
values.clear();
values.put("raw_contact_id", contact_id);
values.put("mimetype", "vnd.android.cursor.item/email_v2");
values.put("data1", list.get(2));
values.put("data2", 2);// 2,Email.TYPE_WORK , 表示工作用Email号码
resolver.insert(uri_data, values);
}


// 以下代码是删除联系人信息的方法。
publicstaticint deleteContacts(ContentResolver resolver, String where,
String[] whereArgs) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.delete(Uri.parse(uri_contacts), where, whereArgs);
}


// 以下代码是查询联系人信息的方法。
publicstatic Cursor selectContactsName(ContentResolver resolver,
String[] projection, String where, String[] whereArgs,
String sortOrder) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
return resolver.query(Uri.parse(uri_contacts), projection, where,
whereArgs, sortOrder);
}


publicstatic List<Map<String, Object>> selectContactsMsg(
ContentResolver resolver, ContentValues values) {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_phones = "content://com.android.contacts/data/phones";
String uri_contacts_emails = "content://com.android.contacts/data/emails";
// 从raw_contacts表中或许联系人的id和联系人的姓名。
Cursor cursor_contacts = resolver.query(Uri.parse(uri_contacts),
new String[] { "_id", "display_name" }, null, null, null);


// 遍历所有的联系人的信息
while (cursor_contacts.moveToNext()) {
int contacts_id = cursor_contacts.getInt(cursor_contacts
.getColumnIndex("_id"));
String display_name = cursor_contacts.getString(cursor_contacts
.getColumnIndex("display_name"));


Map<String, Object> map = new HashMap<String, Object>();
map.put("id", contacts_id);
map.put("display_name", display_name);


// 以下开始获取电话号码
// 根据每个联系人的id再去data表中查找相应的电话号码。
Cursor cursor_phones = resolver.query(
Uri.parse(uri_contacts_phones), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);


// 因为电话号码可能是多个,所以需要再遍历,组合在一起形成一个电话号码的字符串,放到StringBuilder中
StringBuilder sb = new StringBuilder();
while (cursor_phones.moveToNext()) {
sb.append(cursor_phones.getString(1));
sb.append(" | ");
}
// 将生成的电话号码放到map集合中
map.put("phones", sb.toString());


// 以下开始或许Email信息
Cursor cursor_emails = resolver.query(
Uri.parse(uri_contacts_emails), new String[] {
"raw_contact_id", "data1" }, "raw_contact_id=?",
new String[] { contacts_id + "" }, null);
StringBuilder sb2 = new StringBuilder();
while (cursor_emails.moveToNext()) {
sb2.append(cursor_emails.getString(1));
sb2.append(" | ");
}
map.put("emails", sb2.toString());


// 将包含有id、联系人姓名、手机号码、emails的map放到list集合中
list.add(map);
}
return list;
}


// 以下代码是更新联系人姓名的方法。
publicstaticint updateContactsName(ContentValues values,
ContentResolver resolver, String oldName, String newName) {
String uri_contacts = "content://com.android.contacts/raw_contacts";
String uri_contacts_data = "content://com.android.contacts/data";
// 先更新raw_contacts表中的联系人姓名,共有四列需要更新
values.put("display_name", newName);
values.put("display_name_alt", newName);
values.put("sort_key", newName);
values.put("sort_key_alt", newName);
int count1 = resolver.update(Uri.parse(uri_contacts), values,
"display_name=?", new String[] { oldName });
// 再更新data表中联系人的姓名,共有两列
values.clear();
values.put("data1", newName);
values.put("data2", newName);
int count2 = resolver.update(Uri.parse(uri_contacts_data), values,
"data1=? and mimetype_id=?", new String[] { oldName, "7" });
// 返回2,则说明六项都被更新。如果只返回1,则说明没有修改完全
return count1 + count2;
}
}
五、当日作业:
1、完善今天的随堂代码“ContentResolver管理联系人”,增加添加联系人功能,增加删除联系人功能。
2、利用ContentResolver制作管理SDCard上的多媒体文件管理器。
3、利用ContentResolver+AutoCompleteTextView实现自动补全联系人姓名。
posted @ 2015-12-06 20:07  陈旭缘  阅读(549)  评论(0)    收藏  举报
这是什么