Android入门:ContentProvider

一、ContentProvider介绍

ContentProvider翻译为“内容提供者”;

定义:指该应用包含一些方法,供外界访问,其他应用程序可以调用该方法,比如如果应用A创建了一个数据库“test.db”,默认是私有的,即其他应用程序不能对其进行操作,但是如果应用A使用了ContentProvider,则其他应用程序可以访问该数据库;

用途:某个应用对外共享数据;

注意点:和Activity一样,都是Android 的Component之一,如果要创建,则需要在AndroidManifest.xml中设置;

好处:提供了统一的insert,update,delete,query方法,操作任何数据;

二、URI介绍

URI:类似于我们以前使用的URI,但是此处URI的目的是为了能够根据URI以及调用的方法来决定怎样操作数据,比如:

uri="..../person",调用insert方法,则表示需要插入一条person记录;

ContentProvider中使用的URI注意点:

(1)以 content:// 开头;

(2)模式为:content://authorities/path;其中authorities类似于域名或IP,用来标识操作哪个ContentProvider,path表示具体的操作;

举例:

content://org.xiazdong.providers.personprovider/person 表示调用“org.xiazdong.providers.personprovider”的方法,操作person数据;

补充:ContentUris辅助类

URI uri = ContentUris.withAppendId(URI param,int id); //为某个URI添加一个ID

比如param = "content://authorities/person",id=10,则uri = "content://authorities/person/10";

long id = ContentUris.parseId(URI uri); //提取URI中最后的ID

比如uri = "content://authorities/person/10",则返回的id=10;

三、ContentProvider开发步骤简要说明

1.创建一个类,并继承ContentProvider,比如PersonProvider;

2.在AndroidManifest.xml中设置:

<provider android:name=".PersonProvider" android:authorities="org.xiazdong.provides.personprovider"/>

3.定义UriMatcher,

private UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //创建一个URI匹配器,参数为不匹配时的返回值

在onCreate中使用matcher.addURI("authorities","path",code); //加入匹配的URI,如果匹配,则matcher.match(uri)返回code;

如果要匹配:content://authorities/path/数字 ,则matcher.addURI("authorites","path/#",code);

4.重写:

onCreate():用于为操作数据做准备;

insert:插入数据,返回插入的记录所代表的URI;

update:更新数据,返回操作影响的记录行数;

delete:删除数据,返回操作影响的记录行数;

query:查询数据,返回Cursor;

getType:记录的类型,如果操作集合,则必须以vnd.android.cursor.dir开头,如果操作非集合,则必须以vnd.android.cursor.item开头,比vnd.android.cursor.dir/person

5.外部调用:

ContentResolver resolver = this.getContext().getContentResolver();

resolver.insert();

resolver.update();

resolver.delete();

resolver.query();

四、应用实例

AndroidManifest.xml

<provider android:name=".PersonProvider" android:authorities="org.xiazdong.provides.personprovider" ></provider>

PersonProvider.java

package org.xiazdong.db; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class PersonProvider extends ContentProvider{ private DatabaseHelper helper; private SQLiteDatabase db; private UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); @Override public boolean onCreate() { helper = new DatabaseHelper(this.getContext()); //匹配:content://org.xiazdong.provides.personprovider/person,返回值为1 matcher.addURI("org.xiazdong.provides.personprovider", "person", 1); //匹配:content://org.xiazdong.provides.personprovider/person/数字,返回值为2 matcher.addURI("org.xiazdong.provides.personprovider", "person/#", 2); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = helper.getWritableDatabase(); switch(matcher.match(uri)){ case 1: //查询所有记录 return db.query("person", projection, selection, selectionArgs, null, null, null); case 2://查询特定记录 long id = ContentUris.parseId(uri); String where = "id="+id; if(selection!=null&&!"".equals(selection)){ //因为selection可能还包含其他的where语句,需要再加上 "and id=?" where = where + " and "+selection; } return db.query("person", projection, where, selectionArgs, null, null, null); default: throw new IllegalArgumentException("wrong uri"); } } /* * 如果操作集合,则必须以vnd.android.cursor.dir开头 * 如果操作非集合,则必须以vnd.android.cursor.item开头 * */ @Override public String getType(Uri uri) { switch(matcher.match(uri)){ case 1: return "vnd.android.cursor.dir/person"; case 2: return "vnd.android.cursor.item/person"; } } /* * values为插入的数据 * 返回:插入的数据所代表的URI * */ @Override public Uri insert(Uri uri, ContentValues values) { db = helper.getWritableDatabase(); switch(matcher.match(uri)){ case 1: long rowid = db.insert("person", null, values); return ContentUris.withAppendedId(uri, rowid); //返回插入的记录所代表的URI default: throw new IllegalArgumentException("wrong uri"); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { db = helper.getWritableDatabase(); switch(matcher.match(uri)){ case 1:return db.delete("person", selection, selectionArgs); case 2: //删除特定id记录 long id = ContentUris.parseId(uri); String where = "id="+id; if(selection!=null&&!"".equals(selection)){ where += " and "+selection; } return db.delete("person", where, selectionArgs); default: throw new IllegalArgumentException("wrong uri"); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { db = helper.getWritableDatabase(); switch(matcher.match(uri)){ case 1:return db.update("person", values, selection, selectionArgs); case 2: //更新特定id记录 long id = ContentUris.parseId(uri); String where = "id="+id; if(selection!=null&&!"".equals(selection)){ where += " and "+selection; } return db.update("person", values,where, selectionArgs); default: throw new IllegalArgumentException("wrong uri"); } } }

以下我们创建一个测试类:

ContentProviderTest.java

package org.xiazdong.db.test; import org.xiazdong.db.domain.Person; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.test.AndroidTestCase; import android.util.Log; public class ContentProviderTest extends AndroidTestCase{ public void testInsert()throws Exception{ //插入"name=yyy,age=100"的记录 Uri uri = Uri.parse("content://org.xiazdong.provides.personprovider/person"); ContentResolver resolver = this.getContext().getContentResolver(); ContentValues values = new ContentValues(); values.put("name", "yyy"); values.put("age", 100); resolver.insert(uri, values); } public void testUpdate()throws Exception{ //更新id=5的记录为name=yyy,age=100 Uri uri = Uri.parse("content://org.xiazdong.provides.personprovider/person/5"); ContentResolver resolver = this.getContext().getContentResolver(); ContentValues values = new ContentValues(); values.put("name", "yyy"); values.put("age", 100); resolver.update(uri, values, null, null); } public void testDelete()throws Exception{ //删除id=11的记录 Uri uri = Uri.parse("content://org.xiazdong.provides.personprovider/person/5"); //删除id=11的记录 ContentResolver resolver = this.getContext().getContentResolver(); resolver.delete(uri, null, null); } public void testQuery()throws Exception{ //插入全部记录并显示 Uri uri = Uri.parse("content://org.xiazdong.provides.personprovider/person"); //查询所有记录 ContentResolver resolver = this.getContext().getContentResolver(); Cursor cursor = resolver.query(uri, null, null, null, null); while(cursor.moveToNext()){ Person person = new Person(cursor.getInt(cursor.getColumnIndex("id")),cursor.getString(cursor.getColumnIndex("name")),cursor.getInt(cursor.getColumnIndex("age"))); Log.v("ContentProvider", person.toString()); } } }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值