一:什么是ContentPrivider:
一个应用程序可以通过实现一个Content provider的抽象接口将自己的数据共享给其他应用程序,而且Content providers是以类似数据库表的方式将数据暴露。
providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。
要想使应用程序的数据公开化,可通过2种方法:
创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。
那么如何通过统一的接口获取其他应用程序共享的数据呢?
Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。
8.0之后添加权限
compile 'pub.devrel:easypermissions:0.3.0'
二:ContentProvider的使用方法:
1.新建一个ContentProvider类,重写构造方法,insert,delete,getType,onCreate,query,update等方法(根据需要来自行决定重写那些方法)
2.为程序添加一个public static final Uri URI = "content://+<包名>+URIName"静态常量,其他程序通过这个URI来调用此ContentProvider类中的数据
3.为实现数据的存储和读取,起码需要重写onCreate和insert,query方法,下面是重写的具体代码:
public static final Uri URI = Uri.parse("content://andrew.com.contentproviderdemo
.MyContentProviderURI");
SQLiteDatabase database;
@Override
public Uri insert(Uri uri, ContentValues values) {
database.insert("tab","name",values);
return null;
}
@Override
public boolean onCreate() {
database = getContext().openOrCreateDatabase("mycp.db3", Context.MODE_PRIVATE,null); //这段创建数据库的代码,在执行第一次的时候没有问题
//如果第二次运行,会出现错误,解释是说这个要创建的数据库已经存在
//但在使用Sqiliteopenhelper中写出这样的语句,却不会出现这种错误,有可能这是因为sqliteopenhelper
//里面已经解决
//由于暂时简化这种错误的处理时间,采用的办法是运行一遍,成功创建数据库后将代码注释掉
//这样就能解决数据库已经存在的问题
database.execSQL("CREATE TABLE tab("+
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"name TEXT DEFAULT \"\")");
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor cursor = database.query("tab",null,null,null,null,null,null);
return cursor;
}
提供共享的ContentProvider成功运行后;在另外的程序中读取该ContentProvider的信息的代码实现:
Uri URI = Uri.parse("content://andrew.com.contentproviderdemo.MyContentProviderURI");
Cursor cursor = getContentResolver().query(URI,null,null,null,null);
for (cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
String value = cursor.getString(cursor.getColumnIndex("name"));
Toast.makeText(getApplicationContext(),value,Toast.LENGTH_SHORT).show();
}
注:ContentProvider需要在manifests中注册相关信息:
<provider
android:name=".MyContentProvider"
android:authorities="andrew.com.contentproviderdemo.MyContentProviderURI"
android:enabled="true"
android:exported="true">
</provider>
三:android系统管理联系人的URI如下
ContactsContract.Contacts.CONTENT_URI 管理联系人的Uri
ContactsContract.CommonDataKinds.Phone.CONTENT_URI 管理联系人的电话的Uri
ContactsContract.CommonDataKinds.Email.CONTENT_URI 管理联系人的Email的Uri
(注:Contacts有两个表,分别是rawContact和Data,rawContact记录了用户的id和name,其中id栏名称为:ContactsContract.Contacts._ID, name名称栏为ContactContract.Contracts.DISPLAY_NAME,电话信息表的外键id为ContactsContract.CommonDataKinds.Phone.CONTACT_ID,电话号码栏名称为:
ContactsContract.CommonDataKinds.Phone.NUMBER.
data表中Email地址栏名称为:
ContactsContract.CommonDataKinds.Email.DATA
其外键栏为:ContactsContract.CommonDataKinds.Email.CONTACT_ID)
android为多媒体提供的ContentProvider的Uri如下:
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 存储在sd卡上的音频文件
MediaStore.Audio.Media.INTERNAL_CONTENT_URI 存储在手机内部存储器上的音频文件
MediaStore.Audio.Images.EXTERNAL_CONTENT_URI SD卡上的图片文件内容
MediaStore.Audio.Images.INTERNAL_CONTENT_URI 手机内部存储器上的图片
MediaStore.Audio.Video.EXTERNAL_CONTENT_URI SD卡上的视频
MediaStore.Audio.Video.INTERNAL_CONTENT_URI 手机内部存储器上的视频
(注:图片的显示名栏:Media.DISPLAY_NAME,图片的详细描述栏为:Media.DESCRIPTION 图片的保存位置:Media.DATA
短信URI: Content://sms
发送箱中的短信URI: Content://sms/outbox
implementation 'pub.devrel:easypermissions:0.4.2'
通讯录是存放在/data/data/com.android.providers.contacts/databases/contacts2.db,里面主要的表有:
(1)raw_contacts:存放联系人的ID,
_id属性为主键,声明为autoincrement,即不需要手动设置,其他属性也不需要手动设置就有默认值;
display_name属性为姓名;
(2)mimetypes:存放数据的类型,比如"vnd.android.cursor.item/name"表示“姓名”类型的数据,"vnd.android.cursor.item/phone_v2"表示“电话”类型的数据;
(3)data:存放具体的数据;
raw_contact_id属性用来连接raw_contacts表,每条记录表示一个具体数据;我们主要的数据(email、phone等)都存放在data表;
data1属性存放总数据;
data2属性:
-如果此记录存放姓名,则data2存放名;
-如果此记录存放电话,则data2存放类型,比如手机、家电;
-如果此记录存放组织,则data2存放类型,比如公司、其他;
-如果此记录存放地址,则data2存放类型,比如住宅,单位等;
四、编程提示
URI
对raw_contacts表添加、删除、更新操作:
URI = content://com.android.contacts/raw_contacts;
对data表添加、删除、更新操作:
URI = content://com.android.contacts/data;
根据email对data表查询
URI = content://com.android.contacts/data/emails/filter/*
根据电话号码对data表查询
URI = content://com.android.contacts/data/phone/filter/*
如果要根据ID查询电话,可以
URI = content://com.android.contacts/data;
然后where条件为:raw_contact_id=? and mimetype = ?
MIMETYPE
电话:vnd.android.cursor.item/phone_v2
姓名:vnd.android.cursor.item/name
邮件:vnd.android.cursor.item/email_v2
通信地址:vnd.android.cursor.item/postal-address_v2
组织:vnd.android.cursor.item/organization
照片:vnd.android.cursor.item/photo
Data中的常量
Data._ID: "_id"
Data.DISPLAY_NAME:“display_name”
Data.DATA1:“data1”
Data.DATA2:“data2”
Data.RAW_CONTACT_ID:“raw_contact_id”
Data.MIMETYPE:“mimetype”