标签:cursor android uri contentprovider
Android中的Content provider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的方式之一,还有文件,sharePreference,SQLite数据库等方式存储共享数据库,(还有网络数据的存储)
但是ContentProvider更好的提供了数据共享接口的统一性。
在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。
Android提供了一些主要数据类型的Content provider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些android提供的Content provider。可以获得这些Content provider,查询它们包含的数据,当然前提是已获得适当的读取权限。
总的一句:内容提供器是应用程序之间共享数据的接口,Android系统将这种机制应用到方方面面。比如:联系人提供器专为不同应用程序提供联系人数据;设置提供器专为不同应用程序提供系统配置信息,包括内置的设置应用程序等。
查看官方的描述文档
java.lang.Object android.content.ContentProvider
public abstract class ContentProvider
有以上可以知道,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); } @Override public boolean onCreate() { helper = new DBOpenHelper(this.getContext()); return true; } @Override public 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); } } @Override public 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); } } @Override public 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; } @Override public 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); } } @Override public 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>
以下说明如何让别的应用访问该应用的数据库表数据:
以下通过 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); } } }
总结:
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
ContentResolver
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 via
SQLiteDatabase
.
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. The
UriMatcher
class is helpful for parsing URIs.
标签:cursor android uri contentprovider
原文地址:http://blog.csdn.net/u010234084/article/details/42984483