一、简介
Content Provider 组件主要实现在不同程序之间进行数据共享的功能。允许程序访问另一个程序的数据,同时保证被访数据的安全性。使用内容提供器是Android实现跨进程共享数据的标准方式。
一个程序可以使用Content Provider 定义一个URI,提供统一的操作接口,其他程序可以通过此URI访问指定的数据,进行数据的增、删、改、查。
关于URI的知识可以看我之前的文章。
![](https://img.haomeiwen.com/i1938800/0200f5c3bc2ad0ca.png)
二、MIME数据类型:
MIME指定某种扩展名的文件用什么应用程序来打开的方式类型。如指定.html
文件采用text
应用程序打开、指定.pdf
文件采用flash
应用程序打开。 ContentProvider根据 URI 返回MIME类型:
ContentProvider.geType(uri) ;
三、ContentProvider、ContentResolver、ContentObserver 之间的关系:
ContentProvider——内容提供者, 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
ContentResolver——内容解析者, 其作用是按照一定规则访问内容提供者的数据(其实就是调用内容提供者自定义的接口来操作它的数据)。
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。
安卓系统本身提供了ContentProvider让你的app可以获取系统的一些数据库的数据,比如联系人啊,日程表啊等等。我们通过ContentResolver可以获取系统联系人进行增删改查操作。具体例子可以看Android——通讯录这篇文章。
四、ContentResolver的用法:
统一管理不同ContentProvider间的操作,通过URI 即可操作不同的ContentProvider中的数据。
对于每一个应用程序来说,如果想要访问ContentProvider中共享的数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例。
ContentResolver中提供了一系列的方法用于对数据进行CRUD操作,其中insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据。
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://com.example.mycontentprovider");
// 查询
Cursor cursor = resolver.query(uri, null, null, null, null);
// 插入
ContentValues values = new ContentValues();
values.put("key", "value");
resolver.insert(uri, values);
// 更新
values.clear();
values.put("key", "new_value");
resolver.update(uri, values, "key = ?", new String[]{"value"});
// 删除
resolver.delete(uri, "key = ?", new String[]{"value"});
五、ContentProvider的用法:
1、自定义一个ContentProvider类。
public class DBHelper extends SQLiteOpenHelper {
// 数据库名
private static final String DATABASE_NAME = "finch.db";
// 表名
public static final String USER_TABLE_NAME = "user";
public static final String JOB_TABLE_NAME = "job";
private static final int DATABASE_VERSION = 1;
//数据库版本号
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 创建两个表格:用户表 和职业表
db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT)");
db.execSQL("CREATE TABLE IF NOT EXISTS " + JOB_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " job TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public class MyContentProvider extends ContentProvider {
private Context mContext;
DBHelper mDbHelper = null;
SQLiteDatabase db = null;
public static final String AUTOHORITY = "com.example.mycontentprovider";
// 设置ContentProvider的唯一标识
public static final int User_Code = 1;
public static final int Job_Code = 2;
// UriMatcher类使用:在ContentProvider 中注册URI
private static final UriMatcher mMatcher;
static{
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 初始化
mMatcher.addURI(AUTOHORITY,"user", User_Code);
mMatcher.addURI(AUTOHORITY, "job", Job_Code);
// 若URI资源路径 = content://cn.scu.myprovider/user ,则返回注册码User_Code
// 若URI资源路径 = content://cn.scu.myprovider/job ,则返回注册码Job_Code
}
// 以下是ContentProvider的6个方法
/**
* 初始化ContentProvider
*/
@Override
public boolean onCreate() {
mContext = getContext();
// 在ContentProvider创建时对数据库进行初始化
// 运行在主线程,故不能做耗时操作,此处仅作展示
mDbHelper = new DBHelper(getContext());
db = mDbHelper.getWritableDatabase();
// 初始化两个表的数据(先清空两个表,再各加入一个记录)
db.execSQL("delete from user");
db.execSQL("insert into user values(1,'Carson');");
db.execSQL("insert into user values(2,'Kobe');");
db.execSQL("delete from job");
db.execSQL("insert into job values(1,'Android');");
db.execSQL("insert into job values(2,'iOS');");
return true;
}
/**
* 添加数据
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
// 该方法在最下面
String table = getTableName(uri);
// 向该表添加数据
db.insert(table, null, values);
// 当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
mContext.getContentResolver().notifyChange(uri, null);
// // 通过ContentUris类从URL中获取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
return uri;
}
/**
* 查询数据
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
// 该方法在最下面
String table = getTableName(uri);
// // 通过ContentUris类从URL中获取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
// 查询数据
return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
}
/**
* 更新数据
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// 由于不展示,此处不作展开
return 0;
}
/**
* 删除数据
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 由于不展示,此处不作展开
return 0;
}
@Override
public String getType(Uri uri) {
// 由于不展示,此处不作展开
return null;
}
/**
* 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
*/
private String getTableName(Uri uri){
String tableName = null;
switch (mMatcher.match(uri)) {
case User_Code:
tableName = DBHelper.USER_TABLE_NAME;
break;
case Job_Code:
tableName = DBHelper.JOB_TABLE_NAME;
break;
}
return tableName;
}
}
2、在AndroidManifest.xml中注册。
<provider
android:name=".MyContentProvider"
android:authorities="com.example.mycontentprovider"
// 设置此provider是否可以被其他进程使用
android:exported="true" />
网友评论