一、Content Provider基本概念

1、ContentProvider为存储和获取数据提供了统一的接口。ContentProvide使用表的形式来组织数据。

2、使用ContentProvider可以在不同的应用程序之间共享数据。

3、Android为常见的一些数据提供了ContentProvider(包括音频、视频、图片和通讯录等)。

ContentProvider所提供的函数:

query(),insert(),update(),delete(),getType(),onCreate()等。

二、URI(统一资源标识符)

1、每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

2、Android所提供的ContentProvider都存放在android.provider包中。

三、ContentProvider的实现过程

1、定义一个CONTENT_URI常量。

2、定义一个类,继承ContentProvider。

3、实现query,insert,update,delete,getType和onCreate方法。

4、在AndroidManifest.xml当中进行声明。

FirstProviderMetaData.java

package com.android.activity;import android.net.Uri;import android.provider.BaseColumns;/** * 定义contentprovider的常量 * @author Allorry Zhang */public class FirstProviderMetaData {public static final String AUTHORIY = "com.android.activity.FirstContentProvider";//数据库名称public static final String DATABASE_NAME = "FirstProvider.db";//数据库的版本public static final int DATABASE_VERSION = 1;//表名 public static final String USERS_TABLE_NAME = "users";public static final class UserTableMetaData implements BaseColumns{//表名public static final String TABLE_NAME = "users";//访问该ContentProvider的URIpublic static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORIY + "/users");//该ContentProvider所返回的数据类型的定义public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";//列名public static final String USER_NAME = "name";//默认的排序方法public static final String DEFAULT_SORT_ORDER = "_id desc";}}

FirstContentProvider.java

package com.android.activity;import java.util.HashMap;import com.android.activity.FirstProviderMetaData.UserTableMetaData;import com.android.db.DatabaseHelper;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;import android.text.TextUtils;public class FirstContentProvider extends ContentProvider {//检查uri是否符合标准,给uri起一个规则,返回数字public static final UriMatcher uriMatcher;public static final int INCOMING_USER_COLLECTION = 1;public static final int INCOMING_USER_SINGLE = 2;private DatabaseHelper dh;static {uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users",INCOMING_USER_COLLECTION);//#代表iduriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users/#",INCOMING_USER_SINGLE);}//给列起别名public static HashMap<String,String> userProjectionMap;static{userProjectionMap = new HashMap<String,String>();userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);}@Overridepublic int delete(Uri arg0, String arg1, String[] arg2) {System.out.println("delete");return 0;}//根据传入的URI,返回该URI所表示的数据类型@Overridepublic String getType(Uri uri) {System.out.println("getType");switch(uriMatcher.match(uri)){case INCOMING_USER_COLLECTION:return UserTableMetaData.CONTENT_TYPE;case INCOMING_USER_SINGLE:return UserTableMetaData.CONTENT_TYPE_ITEM;default:throw new IllegalArgumentException("Unknown URI" + uri);}}/** * 该函数的返回值是一个Uri,这个Uri表示的是刚刚使用这个函数所插入的数据 * content://mars.cp.FirstContentProvider/users/1 */@Overridepublic Uri insert(Uri uri, ContentValues values) {System.out.println("insert");SQLiteDatabase db = dh.getWritableDatabase();long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);if(rowId > 0){Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);//通知监听器,数据已经改变getContext().getContentResolver().notifyChange(insertedUserUri, null);return insertedUserUri;}throw new SQLException("Failed to insert row into" + uri);}//是一个回调方法,所以说在ContentProvider创建的时候执行 @Overridepublic boolean onCreate() {//打开数据库  dh = new DatabaseHelper(getContext(),FirstProviderMetaData.DATABASE_NAME);System.out.println("onCreate");return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) {SQLiteQueryBuilder qb = new SQLiteQueryBuilder();switch(uriMatcher.match(uri)){case INCOMING_USER_COLLECTION:qb.setTables(UserTableMetaData.TABLE_NAME);qb.setProjectionMap(userProjectionMap);break;case INCOMING_USER_SINGLE:qb.setTables(UserTableMetaData.TABLE_NAME);qb.setProjectionMap(userProjectionMap);qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));break;}String orderBy;if(TextUtils.isEmpty(sortOrder)){orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;}else{orderBy = sortOrder;}SQLiteDatabase db = dh.getWritableDatabase();Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);c.setNotificationUri(getContext().getContentResolver(), uri);System.out.println("query");return c;}@Overridepublic int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {System.out.println("update");return 0;}}

ContentProviderActivity.java

package com.android.activity;import java.util.HashMap;import com.android.activity.FirstProviderMetaData.UserTableMetaData;import com.android.db.DatabaseHelper;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;import android.text.TextUtils;public class FirstContentProvider extends ContentProvider {//检查uri是否符合标准,给uri起一个规则,返回数字public static final UriMatcher uriMatcher;public static final int INCOMING_USER_COLLECTION = 1;public static final int INCOMING_USER_SINGLE = 2;private DatabaseHelper dh;static {uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);uriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users",INCOMING_USER_COLLECTION);//#代表iduriMatcher.addURI(FirstProviderMetaData.AUTHORIY, "/users/#",INCOMING_USER_SINGLE);}//给列起别名public static HashMap<String,String> userProjectionMap;static{userProjectionMap = new HashMap<String,String>();userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);}@Overridepublic int delete(Uri arg0, String arg1, String[] arg2) {System.out.println("delete");return 0;}//根据传入的URI,返回该URI所表示的数据类型@Overridepublic String getType(Uri uri) {System.out.println("getType");switch(uriMatcher.match(uri)){case INCOMING_USER_COLLECTION:return UserTableMetaData.CONTENT_TYPE;case INCOMING_USER_SINGLE:return UserTableMetaData.CONTENT_TYPE_ITEM;default:throw new IllegalArgumentException("Unknown URI" + uri);}}/** * 该函数的返回值是一个Uri,这个Uri表示的是刚刚使用这个函数所插入的数据 * content://mars.cp.FirstContentProvider/users/1 */@Overridepublic Uri insert(Uri uri, ContentValues values) {System.out.println("insert");SQLiteDatabase db = dh.getWritableDatabase();long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);if(rowId > 0){Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);//通知监听器,数据已经改变getContext().getContentResolver().notifyChange(insertedUserUri, null);return insertedUserUri;}throw new SQLException("Failed to insert row into" + uri);}//是一个回调方法,所以说在ContentProvider创建的时候执行 @Overridepublic boolean onCreate() {//打开数据库  dh = new DatabaseHelper(getContext(),FirstProviderMetaData.DATABASE_NAME);System.out.println("onCreate");return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) {SQLiteQueryBuilder qb = new SQLiteQueryBuilder();switch(uriMatcher.match(uri)){case INCOMING_USER_COLLECTION:qb.setTables(UserTableMetaData.TABLE_NAME);qb.setProjectionMap(userProjectionMap);break;case INCOMING_USER_SINGLE:qb.setTables(UserTableMetaData.TABLE_NAME);qb.setProjectionMap(userProjectionMap);qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));break;}String orderBy;if(TextUtils.isEmpty(sortOrder)){orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;}else{orderBy = sortOrder;}SQLiteDatabase db = dh.getWritableDatabase();Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);c.setNotificationUri(getContext().getContentResolver(), uri);System.out.println("query");return c;}@Overridepublic int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {System.out.println("update");return 0;}}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.android.activity"      android:versionCode="1"      android:versionName="1.0">    <uses-sdk android:minSdkVersion="10" />    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity android:name=".ContentProviderActivity"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity><provider android:name="com.android.activity.FirstContentProvider"  android:authorities="com.android.activity.FirstContentProvider"></provider>    </application></manifest>

main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><TextView      android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/hello"    /><Button android:id="@+id/insert"    android:layout_width="fill_parent"     android:layout_height="wrap_content" android:text="插入数据"/><Button android:id="@+id/query"    android:layout_width="fill_parent"     android:layout_height="wrap_content" android:text="查询数据"/></LinearLayout>

其实很少能使用到自己定义实现的ContentProvider,平时只要知道API定义好的ContentProvider的使用即可。

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. Android(安卓)代码控制手机数据网络的开关(5.0以上)
  3. Android(安卓)如何用HttpClient 以Get方式获取数据并添加http头
  4. Android(安卓)Parcel实现反向Binder通信
  5. android中的数据存储 收藏
  6. android 系统重启关机 方法 非常好的一篇文章
  7. Android(安卓)Framework下StageFright框架流程解读
  8. Android(安卓)自定义码表图
  9. Android(安卓)Fragment与Fragment之间数据获取

随机推荐

  1. 让你的代码减少三倍!使用kotlin开发Androi
  2. Android(安卓)电量分析之Battery Histori
  3. Android(安卓)6.0运行时权限 (危险权限)
  4. android自定义大小对话框
  5. Android原生(Native)C开发之六:libpng移植
  6. Android+本地记事本(上)------实现登陆注
  7. Android(安卓)PinyinIME Debug 调试
  8. Android(安卓)MatrixCursor的详解
  9. adb shell 查看系统属性(用来判断特殊的操
  10. ListView中几个需要注意的属性