一 理解
1.为什么要有ContentProvider?
1) 功能需求:一个应用需要访问另一个应用的数据库表数据
2) 实际情况:一个应用的数据库文件是应用私有的,其它应用不能直接访问
2.ContentProvider是什么?
1) ContentProvider是四大应用组件之一
2) 当前应用使用ContentProvider将数据库表数据操作暴露给其它应用访问
3) 其它应用需要使用ContentResolver来调用ContentProvider的方法
4) 它们之间的调用是通过Uri来进行交流的
二 相关API
1. ContentProvider: 内容提供者
public abstract boolean onCreate(); //provider对象创建后调用(应用安装成功或手机启动完成)
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs); //查询表数据
Uri insert(Uri uri, ContentValues values); //插入表数据
int delete(Uri uri, String selection, String[] selectionArgs); //删除表数据
int update(Uri uri, ContentValues values, String selection, String[] selectionArgs); //更新表数据
2.ContentResolver: 内容提供者的解析类
context.getContentResolver(); //得到ContentResolver的对象
insert() delete() update() query() //调用provider进行数据库增删改查操作
registerContentObserver(Uri uri, boolean notify, ContentObserver observer); //注册uri的监听
unregisterContentObserver(ContentObserver observer); //解注册uri的监听
notifyChange(Uri uri, ContentObserver observer) //通知监听器
3. Uri: 包含一个具有一定格式字符串所对应资源的类
Uri static parse(String uriString); //得到其对象
4. UriMatcher: 用来识别uri的一个uri容器
void addURI(String authority, String path, int code); //添加一个合法的URI
int match(Uri uri); //匹配指定的uri, 返回匹配码
5.ContentUris: 操作uri的工具类
long parseId(Uri contentUri); //解析uri,得到其中的id
Uri withAppendedId(Uri contentUri, long id); //添加id到指定的uri中
三 自定义ContentProvider
1. 编写ContentProvider子类
class StudentContentProvider extends ContentProvider{
//实现insert,delete,update和query等方法
}
2. 在manifest.xml中注册
<provider android:name="com.atguigu.l09_provider.PersonProvider"
android:authorities="com.atguigu.l09_provider.personprovider"
android:exported="true">
</provider>
四 使用ContentResolver访问ContentProvider
1). 得到ContentResolver对象
context.getContentResoler();
2). 使用其对象
insert()
delete()
update()
query()
//系统自动找到匹配的ContentProvider对象来操作数据
五 代码
provider中DBHelper类
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "atguigu.db", null, 1);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
//建表
db.execSQL("create table person(_id integer primary key autoincrement, name varchar)");
db.execSQL("insert into person (name) values ('Tom')");
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
}
/**
* 操作person表的provider类
* @author YY
*
*/
public class PersonProvider extends ContentProvider {
//用来存放所有合法的Uri的容器
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//保存一些合法的uri
// content://com.atguigu.l09_provider.personprovider/person
// content://com.atguigu.l09_provider.personprovider/person/3
static {
matcher.addURI("com.atguigu.l09_provider.personprovider", "person", 1);
matcher.addURI("com.atguigu.l09_provider.personprovider", "person/#", 2);
}
private DBHelper dbHelper;
public PersonProvider() {
Log.e("TAG", "PersonProvider()");
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id删除
* content://com.atguigu.l09_provider.personprovider/person/3 根据id删除
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.e("TAG", "PersonProvider delete()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri,返回code
int code = matcher.match(uri);
int deleteCount = -1;
//如果合法,进行删除
if(code==1){
deleteCount = database.delete("person", selection, selectionArgs);
} else if(code==2) {
long id = ContentUris.parseId(uri);
deleteCount = database.delete("person", "_id="+id, null);
} else {
//如果不合法,抛出异常
database.close();
throw new RuntimeException("删除的uri不合法");
}
database.close();
return deleteCount;
}
@Override
public String getType(Uri arg0) {
// TODO Auto-generated method stub
return null;
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id查询
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.e("TAG", "PersonProvider insert()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri,返回code
int code = matcher.match(uri);
//如果合法,进行插入
if(code==1){
long id = database.insert("person", null, values);
//将id添加到uri中
uri = ContentUris.withAppendedId(uri, id);
database.close();
return uri;
} else {
//如果不合法,抛出异常
database.close();
throw new RuntimeException("插入的uri不合法");
}
}
@Override
public boolean onCreate() {
Log.e("TAG", "PersonProvider onCreate()");
dbHelper = new DBHelper(getContext());
return false;
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id查询
* content://com.atguigu.l09_provider.personprovider/person/3 根据id查询
*/
@Override
public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,
String arg4) {
Log.e("TAG", "PersonProvider query()");
SQLiteDatabase database = dbHelper.getReadableDatabase();
//1.匹配uri,返回code
int code = matcher.match(uri);
Log.e("TAG", "PersonProvider query()"+code);
//如果合法,进行查询
if(code==1){//不根据id查询
Cursor cursor = database.query("person", arg1, arg2, arg3, null, null, null);
return cursor;
} else if(code==2){//根据id查询
//得到id
long id = ContentUris.parseId(uri);
//查询
Cursor cursor = database.query("person", arg1, "_id=?", new String[]{id+""}, null, null, null);
return cursor;
} else {//如果不合法,抛出异常
throw new RuntimeException("查询的uri不合法");
}
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id更新
* content://com.atguigu.l09_provider.personprovider/person/3 根据id更新
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Log.e("TAG", "PersonProvider update()");
SQLiteDatabase database = dbHelper.getReadableDatabase();
//1.匹配uri,返回code
int code = matcher.match(uri);
int updateCount = -1;
//如果合法,进行查询
if(code==1){//不根据id查询
updateCount = database.update("person", values, selection, selectionArgs);
} else if(code==2){//根据id查询
//得到id
long id = ContentUris.parseId(uri);
//更新
updateCount = database.update("person", values, "_id="+id, null);
} else {//如果不合法,抛出异常
database.close();
throw new RuntimeException("更新的uri不合法");
}
database.close();
return updateCount;
}
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/*
* 通过ContentResolver调用ContentProvider查询所有记录
*/
public void query(View v){
//得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2.调用其query,得到cursor
//根据id查询
Uri uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person/1");
//不根据id查询
uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person");
Cursor cursor = resolver.query(uri, null, null, null, null);
//3.取出cursor中的数据,并显示
while(cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
Toast.makeText(this, id+" : "+name, 0).show();
}
cursor.close();
}
/*
* 通过ContentResolver调用ContentProvider插入一条记录
*/
public void insert(View v){
//得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2.调用其insert
Uri uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person");
ContentValues values = new ContentValues();
values.put("name", "JACK");
uri = resolver.insert(uri, values);
Toast.makeText(this, uri.toString(), 0).show();
}
/*
* 通过ContentResolver调用ContentProvider更新记录
*/
public void update(View v){
//得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2.执行update
Uri uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person/2");
ContentValues values = new ContentValues();
values.put("name", "JACK2");
int updateCount = resolver.update(uri, values, null, null);
Toast.makeText(this, "updateCount="+updateCount, 1).show();
}
/*
* 通过ContentResolver调用ContentProvider删除一条记录
*/
public void delete(View v){
//得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2.执行delete
Uri uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person/2");
int deleteCount = resolver.delete(uri, null, null);
Toast.makeText(this, "deleteCount="+deleteCount, 1).show();
}
}