ContentProvider详细用法记录和总结

来源:互联网 发布:手机虚拟摄像头软件 编辑:程序博客网 时间:2024/05/18 00:34

 Android中的Content provider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的方式之一,还有文件,sharePreference,SQLite数据库等方式存储共享数据库,(还有网络数据的存储)

但是ContentProvider更好的提供了数据共享接口的统一性。

在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。

Android提供了一些主要数据类型的Content provider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些android提供的Content provider。可以获得这些Content provider,查询它们包含的数据,当然前提是已获得适当的读取权限。


总的一句:内容提供器是应用程序之间共享数据的接口,Android系统将这种机制应用到方方面面。比如:联系人提供器专为不同应用程序提供联系人数据;设置提供器专为不同应用程序提供系统配置信息,包括内置的设置应用程序等。


查看官方的描述文档

android.content
类 ContentProvider

java.lang.Object  继承者 android.content.ContentProvider
所有已实现的接口:
ComponentCallbacks
直接已知子类:
SearchRecentSuggestionsProvider

public abstract class ContentProvider
extends Object
implements ComponentCallbacks

有以上可以知道,ContentProvider是一个抽象类;因此使用的时候需要继承并实现里面的方法;

以下的方法需要被实现:

  • query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) which returns data to the caller
  • insert(android.net.Uri, android.content.ContentValues) which inserts new data into the content provider
  • update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) which updates existing data in the content provider
  • delete(android.net.Uri, java.lang.String, java.lang.String[]) which deletes data from the content provider
  • getType(android.net.Uri) which returns the MIME type of data in the content provider 

另外一个常用的方法是Oncreate()方法,在里面我们可以对一些对象进行初始化,比如说 DBOpenHelper。


以下是一个完整的ContentProvider 的例子:

person表的字段:personid name phone amount

第一步:建立ContentProvider 的子类

package com.my.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;import com.my.service.DBOpenHelper;public class PersonProvider extends ContentProvider {private DBOpenHelper helper;private final static UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);private final static int PERSONS = 1;private final static int PERSON = 2;static {MATCHER.addURI("db.PersonProvider", "person", PERSONS);MATCHER.addURI("db.PersonProvider", "person/#", PERSON);}@Overridepublic boolean onCreate() {helper = new DBOpenHelper(this.getContext());return true;}@Overridepublic String getType(Uri uri) {switch (MATCHER.match(uri)) {case PERSONS:return "vnd.android.cursor.dir/person";case PERSON:return "vnd.android.cursor.item/person";default:throw new IllegalArgumentException("this is Unknown Uri:"+ uri);}}@Overridepublic Uri insert(Uri uri, ContentValues values) {SQLiteDatabase db = helper.getWritableDatabase();switch (MATCHER.match(uri)) {case PERSONS:long rowid = db.insert("person", "name", values);Uri insertUri = ContentUris.withAppendedId(uri, rowid);this.getContext().getContentResolver().notifyChange(uri, null);//发出数据变化通知return insertUri;default:throw new IllegalArgumentException("Unkonw Uri" + uri);}}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {SQLiteDatabase db = helper.getWritableDatabase();int num = 0;switch (MATCHER.match(uri)) {case PERSONS:num = db.delete("person", selection, selectionArgs);break;case PERSON:long rowid = ContentUris.parseId(uri);String where = "personid=" + rowid;if (selection != null && "".equals(selection.trim())) {where = where + " and " + selection;}num = db.delete("person", where, selectionArgs);break;default:throw new IllegalArgumentException("this is Unknown Uri:" + uri);}return num;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase db = helper.getReadableDatabase();switch (MATCHER.match(uri)) {case PERSONS:return db.query("person", projection, selection, selectionArgs,null, null, sortOrder);case PERSON: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 Unknown Uri:" + uri);}}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase db = helper.getWritableDatabase();int num = 0;switch (MATCHER.match(uri)) {case PERSONS:num = db.update("person", values, selection, selectionArgs);break;case PERSON: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 Unknown Uri:" + uri);}return num;}}

第二步:注册provider


        <Application >
<span style="white-space:pre"></span><provider            android:name=".PersonProvider"//这里注意package路径            android:authorities="db.PersonProvider" />
</application>



主要通过这两步,那么一个ContentProvider 就已经完成了,对于其他应用来说就可以访问改应用中的person数据库数据。


以下说明如何让别的应用访问该应用的数据库表数据:

以下通过 AndroidTestCase 进行测试:

建立安卓项目,AndroidManifest.xml主要配置如下

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.junitest"    android:versionCode="1"    android:versionName="1.0" >    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <uses-library android:name="android.test.runner" />        <activity            android:name=".MainActivity"            android:label="test" >            <intent-filter android:label="test" >                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>    <instrumentation        android:name="android.test.InstrumentationTestRunner"        android:targetPackage="com.example.junitest" >    </instrumentation></manifest>


随表建立一个类便可以测试ContentProvider了,注意包路径问题



package com.example.test;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.test.AndroidTestCase;public class ProviderTest extends AndroidTestCase {public void testinsert() {Uri uri = Uri.parse("content://db.PersonProvider/person");ContentResolver resolver = this.getContext().getContentResolver();ContentValues values = new ContentValues();values.put("name", "test");values.put("phone", "123456789");values.put("amount", 9999);resolver.insert(uri, values);}public void testdelete() {// Uri uri = Uri.parse("content://db.PersonProvider/person");// ContentResolver resolver = this.getContext().getContentResolver();// resolver.delete(uri, null, null);Uri uri = Uri.parse("content://db.PersonProvider/person/52");ContentResolver resolver = this.getContext().getContentResolver();resolver.delete(uri, null, null);}public void testupdate() {// Uri uri = Uri.parse("content://db.PersonProvider/person");// ContentResolver resolver = this.getContext().getContentResolver();//// ContentValues values = new ContentValues();// values.put("phone", "");// resolver.update(uri, values, null, null);Uri uri = Uri.parse("content://db.PersonProvider/person/45");ContentResolver resolver = this.getContext().getContentResolver();ContentValues values = new ContentValues();values.put("phone", "111111111111111111111111111111");resolver.update(uri, values, null, null);}public void testquery() {// Uri uri = Uri.parse("content://db.PersonProvider/person");// ContentResolver resolver = this.getContext().getContentResolver();// Cursor cursor = resolver.query(uri, null, null, null, null);Uri uri = Uri.parse("content://db.PersonProvider/person/45");ContentResolver resolver = this.getContext().getContentResolver();Cursor cursor = resolver.query(uri, null, null, null, null);while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndex("name"));System.out.println(name);}}}


run as android junit test 就可以进行测试了。

总结:


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 singleContentResolver interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don't need to share data amongst multiple applications you can use a database directly viaSQLiteDatabase.

For more information, read Content Providers.

When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority. The content provider can interpret the rest of the URI however it wants. TheUriMatcher class is helpful for parsing URIs.


0 0
原创粉丝点击