作为四大组件之一的ContentProvider,其作用是对外共享数据,相对文件和数据库存储来说,它的好处是统一了数据访问方式。 先来看看基本的介绍: Class Overview Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single When a request is made via a The primary methods that need to be implemented are:
Data access methods (such as Requests to 这里有个Uri匹配类:UriMatcher,它的基本介绍如下: Class OverviewUtility class to aid in matching URIs in content providers. To use this class, build up a tree of private static final int PEOPLE = 1; private static final int PEOPLE_ID = 2; private static final int PEOPLE_PHONES = 3; private static final int PEOPLE_PHONES_ID = 4; private static final int PEOPLE_CONTACTMETHODS = 7; private static final int PEOPLE_CONTACTMETHODS_ID = 8; private static final int DELETED_PEOPLE = 20; private static final int PHONES = 9; private static final int PHONES_ID = 10; private static final int PHONES_FILTER = 14; private static final int CONTACTMETHODS = 18; private static final int CONTACTMETHODS_ID = 19; private static final int CALLS = 11; private static final int CALLS_ID = 12; private static final int CALLS_FILTER = 15; private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI("contacts", "people", PEOPLE); sURIMatcher.addURI("contacts", "people/#", PEOPLE_ID); sURIMatcher.addURI("contacts", "people/#/phones", PEOPLE_PHONES); sURIMatcher.addURI("contacts", "people/#/phones/#", PEOPLE_PHONES_ID); sURIMatcher.addURI("contacts", "people/#/contact_methods", PEOPLE_CONTACTMETHODS); sURIMatcher.addURI("contacts", "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID); sURIMatcher.addURI("contacts", "deleted_people", DELETED_PEOPLE); sURIMatcher.addURI("contacts", "phones", PHONES); sURIMatcher.addURI("contacts", "phones/filter/*", PHONES_FILTER); sURIMatcher.addURI("contacts", "phones/#", PHONES_ID); sURIMatcher.addURI("contacts", "contact_methods", CONTACTMETHODS); sURIMatcher.addURI("contacts", "contact_methods/#", CONTACTMETHODS_ID); sURIMatcher.addURI("call_log", "calls", CALLS); sURIMatcher.addURI("call_log", "calls/filter/*", CALLS_FILTER); sURIMatcher.addURI("call_log", "calls/#", CALLS_ID); } Then when you need to match against a URI, call public String getType(Uri url) { int match = sURIMatcher.match(url); switch (match) { case PEOPLE: return "vnd.android.cursor.dir/person"; case PEOPLE_ID: return "vnd.android.cursor.item/person"; ... snip ... return "vnd.android.cursor.dir/snail-mail"; case PEOPLE_ADDRESS_ID: return "vnd.android.cursor.item/snail-mail"; default: return null; } } instead of: public String getType(Uri url) { List pathSegments = url.getPathSegments(); if (pathSegments.size() >= 2) { if ("people".equals(pathSegments.get(1))) { if (pathSegments.size() == 2) { return "vnd.android.cursor.dir/person"; } else if (pathSegments.size() == 3) { return "vnd.android.cursor.item/person"; ... snip ... return "vnd.android.cursor.dir/snail-mail"; } else if (pathSegments.size() == 3) { return "vnd.android.cursor.item/snail-mail"; } } } return null; }
其他应用可以通过ContentResolver的实例来访问内容提供者的数据,它的基本介绍:
Class OverviewThis class provides applications access to the content model. 通过它的insert()、delete()、update()、query()来对内容提供者数据进行添删改查操作。
下面通过一个实例来看一下如何使用ContentProvider进行数据共享 我们需要建立两个project:Android_ContentProvider和Android_ContentProvider_Test,分别作为内容提供者和对数据访问者。 在前者中,我们定义一个自己的PersonProvider,提供对person表的数据操作,在后者中,我们通过Junit Test 的test方法来完成数据操作测试。 Android_ContentProvider的目录结构: 这里的布局文件和Ui等没有意义,我们重点看一下DBOpenHelper和PersonProvider两个类,分别是数据库工具类和自定义内容提供者, DBOpenHelper.java代码如下:
package com.wujay.provider.service; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class DBOpenHelper extends SQLiteOpenHelper{ /** * 构造函数 * @param context */ public DBOpenHelper(Context context) { super(context, "wujay.db", null, 2); } /* * 初始化 */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table person(personId integer primary key autoincrement, name varchar(20)," + "phone varchar(12) null,amount varchar(20) null)"); } /* * 更新操作 */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table person add amount integer null"); } } 在这个类中实现数据库的创建以及更新操作。 PersonProvider.java代码如下:
package com.wujay.provider.db; import com.wujay.provider.service.DBOpenHelper; 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 DBOpenHelper dbOpenHelper; private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); private static int PERSONS = 1; //对所有数据操作 private static int PERSON = 2; //操作指定的数据 /* * 静态代码块 */ static{ MATCHER.addURI("com.wujay.providers.personprovider", "person", PERSONS); MATCHER.addURI("com.wujay.providers.personprovider", "person/#", PERSON); } /* * 初始化 */ @Override public boolean onCreate() { dbOpenHelper = new DBOpenHelper(getContext()); return false; } /* * 根据条件查询 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); int num = 0; switch (MATCHER.match(uri)) { case 1: return db.query("person", projection, selection, selectionArgs, null, null, sortOrder); case 2: long rowId = ContentUris.parseId(uri); String where = "personId=" + rowId; if(selection!=null && "".equals(selection.trim())){ where += " and "+selection; } return db.query("person", projection, where, selectionArgs, null, null, sortOrder); default: throw new IllegalArgumentException("this is a unknown URI:"+uri); } } /* * 用于返回当前Uri所代表的数据的MIME类型 */ @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"; default: throw new IllegalArgumentException("this is a unknown URI:"+uri); } } /* * 插入数据 */ @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case 1: long rowId = db.insert("person", "name", values); Uri insertUri = ContentUris.withAppendedId(uri, rowId); break; default: throw new IllegalArgumentException("this is a unknown URI:"+uri); } return null; } /* * 删除数据 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int num = 0; switch (MATCHER.match(uri)) { case 1: num = db.delete("person", selection, selectionArgs); break; case 2: long rowId = ContentUris.parseId(uri); String where = "personId=" + rowId; if(selection!=null && "".equals(selection.trim())){ where += " and "+selection; } num = db.delete("person", where, selectionArgs); break; default: throw new IllegalArgumentException("this is a unknown URI:"+uri); } return num; } /* * 修改数据 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); int num = 0; switch (MATCHER.match(uri)) { case 1: num = db.update("person", values, selection, selectionArgs); break; case 2: long rowId = ContentUris.parseId(uri); String where = "personId=" + rowId; if(selection!=null && "".equals(selection.trim())){ where += " and "+selection; } num = db.update("person", values, where, selectionArgs); break; default: throw new IllegalArgumentException("this is a unknown URI:"+uri); } return num; } } |