【Android基础笔记15】ContentProvider实现数据共享


一、ContentProvider简介:
(一)、引入:
         数据库在Android当中是私有的,不能将数据库设为WORLD_READABLE,每个数据库都只能创建它的包访问。这意味着只有创建这个数据库的应用程序才可访问它。也就是说不能跨越进程和包的边界,直接访问别的应用程序的数据库。那么如何在应用程序间交换数据呢? 如果需要在进程间传递数据,可以使用ContentProvider来实现。

(二)、ContentProvider的功能和意义:
        为了在应用程序之间交换数据,Android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API。当一个应用程序需要把自己的数据暴露给其他应用程序使用时,该应用程序可以通过提供ContentProvider来实现;而其他应用程序需要使用这些数据时,可以通过ContentResolver来操作ContentProvider暴露的数据。
        一旦某个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作被暴露的内部数据,包括增加数据、删除数据、修改数据、查询数据等。
        虽然大部分使用ContentProvider操作的数据都来自于数据库,但是也可以来自于文件、SharedPreferences、XML或网络等其他存储方式。

(三)、核心类:
    1、ContentProvider:(A应用暴露数据)
  •  一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去;
  •  外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以修改程序的数据。
    2、ContentResolver:(操作A应用所暴露的数据)
  •   外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据
  •   ContentResolve可以理解成是HttpClient的作用。
    3、 Uri:Uri是ContentResolver和ContentProvider进行数据交换的标识。
  •   每个ContentProvider提供公共的URI来唯一标识其数据集。管理多个数据集的(多个表)的 ContentProvider 为每个数据集提供了单独的URI。
  •   Uri 的标准前缀:以“content://”作为前缀,这个是标准的前缀,表示该数据由 ContentProvider 管理。
  •   Uri 的authority部分:该部分是完整的类名。(使用小写形式)。
  •   Uri 的path部分(资源部分、数据部分): 用于决定哪类数据被请求。
  •   被请求的特定记录的id值。如果请求不仅限于某个单条数据,该部分及其前面的斜线应该删除。
  •   为了将一个字符串转换成Uri,Android中提供了Uri的parse()静态方法来实现。
        
【备注:】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则必须提供足够的信息来定位,所以,是绝对的。

(四)、系统内置的ContentProvider
1、Contacts:获取、修改、保存联系人的信息;
2、MediaStore:访问声音、视频、图片等多媒体文件;
3、CallLog :查看或更新通话记录;
4、Browser:读取或修改浏览历史、网络搜索、书签;
5、Setting:查看和获取蓝牙设置、铃声设置等设备首选项。


二、使用ContentResolver 管理联系人:【重点】
(一)、 使用ContentResolver 操作数据的步骤
1、调用Context的getContentResolver()方法获得ContentResolver 对象;
2、调用使用ContentResolver 的insert()、delete()、update()、query()方法操作数据。
  • Uri insert(Uri uri, ContentValues values)
  • int delete(Uri uri, String where, String[] whereArgs)
  • Cursor query(Uri uri, String[] projection, String where, String[] whereArgs, String sortOrder)
  • int update(Uri uri, ContentValues values, String where, String[] whereArgs)
参数解释:
String   where:表示带有占位符的where子句组成的字符串;
String[]   whereArgs:表示替换where参数中占位符后的数据组成的字符串数组;
String   sortOrder:表示select语句中的order by子句组成的字符串;
String[]   projection:表示select语句中需要查询的所有的字段组成的字符串数组。
ContentValues values:是由数据库中表字段和往该字段中放置的数据所组成的键值对对象。
【备注:】以上四个方法的参数分别是2、3、4、5个。

(二)、 联系人管理中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

不过为了方便记忆,系统中提供了以下常量来替代以上的Uri字符串。
  • Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
  • Uri PHONE_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
  • Uri EMAIL_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;

(三)、示例代码1——查看通讯录中的联系人姓名、id、电话、Email等信息:

public List<Map<String, Object>> getContactsList(){

List<Map<String, Object>> list=new ArrayList<Map<String,Object>>();

Cursor cursor=contentResolver.query(contactUri, null, null, null, null);//查询raw_contacts表中的数据 _id display_name

while(cursor.moveToNext()){

Map<String, Object> map=new HashMap<String, Object>();

//获取联系人的id

int contactId=cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));

//获取联系人的名字

String display_name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

map.put(ContactsContract.Contacts._ID, contactId);

map.put(ContactsContract.Contacts.DISPLAY_NAME, display_name);

//根据当前联系人的id查询在data表中的电话的信息

Cursor phoneCursor=contentResolver.query(phoneUri, null,ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID+"=?"

new String[]{contactId+""}, null);

String phone="";

while(phoneCursor.moveToNext()){

//获取当前联系人的电话号码

phone=phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

System.out.println("------phone-----"+phone);

}

map.put("phone", phone);

//根据当前联系人的id查询data表中的邮箱的信息

Cursor emailCursor=contentResolver.query(emailUri, null,ContactsContract.CommonDataKinds.Email.RAW_CONTACT_ID+"=?"

new String[]{contactId+""}, null);

String email="";

while(emailCursor.moveToNext()){

//获取当前联系人的email信息

email=emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));

}

map.put(ContactsContract.CommonDataKinds.Email.DATA, email);

list.add(map);

}

return list;

}

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

public void insertContact(){

//向raw_contacts插入空列数据 获取到唯一的id

ContentValues values=new ContentValues();

Uri newUri=contentResolver.insert(RawContacts.CONTENT_URI, values);

long contactId=ContentUris.parseId(newUri);//得到当前插入的联系人的id

//向data中插入名字数据

values=new ContentValues();

values.put(Data.RAW_CONTACT_ID, contactId);

values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);//标示当前data中存储的联系人姓名的数据

values.put(StructuredName.DISPLAY_NAME, "wangdabao");//向名称字段插入数据

contentResolver.insert(doUri, values);

//向data表中插入电话数据

values=new ContentValues();

values.put(Data.RAW_CONTACT_ID, contactId);

values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);//插入电话的类型

values.put(Phone.NUMBER, "010-54328190");//插入电话号码

contentResolver.insert(doUri, values);

//向data中插入邮箱数据

values=new ContentValues();

values.put(Data.RAW_CONTACT_ID, contactId);

values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);//插入邮箱的类型

values.put(Email.DATA, "wangdb@qq.com");

contentResolver.insert(doUri, values);

}




三、系统自带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.Audio.Video.EXTERNAL_CONTENT_URI         存储在 SD卡上的视频
  3. MediaStore.Audio.Images.EXTERNAL_CONTENT_URI       存储在 SD卡上的图片文件内容
  4. MediaStore.Audio.Media.INTERNAL_CONTENT_URI         手机内部存储器上的音频文件 
  5. MediaStore.Audio.Video.INTERNAL_CONTENT_URI          手机内部存储器上的视频
  6. MediaStore.Audio.Images.INTERNAL_CONTENT_URI        手机内部存储器上的图片

【数据库中主要字段:】

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

(三)、短信Uri:

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

  1. 短信手机号码 : address
  2. 短信标题:  subject
  3. 短信内容:body
  4.  短信发送时间戳:date
  5. 短信类型:type

(四)、通话记录Uri:

  1.  content://call_log/calls               所有通话记录

E7FB2600-75A1-4E32-AEE1-0521CE942985.png

访问权限
49E3855D-4E98-4534-A8DB-4989A65AC6D4.png


2.  content://sms              所有短信记录

11.png


访问权限
12.png






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值