Android18_Content Provider
16lz
2021-01-26
一、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的使用即可。
更多相关文章
- 一句话锁定MySQL数据占用元凶
- Android(安卓)代码控制手机数据网络的开关(5.0以上)
- Android(安卓)如何用HttpClient 以Get方式获取数据并添加http头
- Android(安卓)Parcel实现反向Binder通信
- android中的数据存储 收藏
- android 系统重启关机 方法 非常好的一篇文章
- Android(安卓)Framework下StageFright框架流程解读
- Android(安卓)自定义码表图
- Android(安卓)Fragment与Fragment之间数据获取