Android学习笔记ContentProvider

来源:互联网 发布:cx域名不值钱吗 编辑:程序博客网 时间:2024/06/15 22:12

1.ContentProvider是个什么?

ContentProvider——内容提供者。它是一个类,这个类主要是对Android系统中进行共享的数据进行包装,并提供了一组统一的访问接口供其他程序调用。这些被共享的数据,可以使系统自己的也可以使我们个人应用程序中的数据。

2.ContentProvider有什么作用?

在Android中,数据的存储有很多种方式,最常用的就是SQLite和XML文件方式。在不同的应用程序间,其实数据是不能直接被相互访问和操作的,在这种情况下,ContentProvider很好的被用来解决了不同应用程序间数据共享的问题。
其实在Android系统中,已经为我们提供了许多ContentProvider,如:Contacts、Browser、CallLog、Settings等等。那么,Android系统中提供了这么多的ContentProvider,另外还有我们自己公开的共享数据,我们在写程序的时候,怎么才能让我们的应用程序知道去哪儿取、如何取这些数据呢?我们自然的会想到URI。

3.URI中的方法

 URI(Uniform Resource Identifier)——统一资源定位符,URI在ContentProvider中代表了要操做的数据。

    在Android系统中通常的URI格式为:content://LiB.cprovider.myprovider.Users/User/21

    在万维网访问时通常用的URI格式为:http://www.cccc.com/xx/zz

content://——schema,这个是Android中已经定义好的一个标准。
LiB.cprovider.myprovider.Users——authority(主机名),用于唯一标识这个ContentProvider,外部调用者通过这个authority来找到它。相当于www.cccc.com,代表的是我们ContentProvider所在的”域名”,这个”域名”在我们Android中一定要是唯一的,否则系统怎么能知道该找哪一个Provider呢?所以一般情况下,建议采用完整的包名加类名来标识这个ContentProvider的authority。
/User/21——路径,用来标识我们要操作的数据。/user/21表示的意思是——找到User中id为21的记录。其实这个相当于/xxx/zzz。
    综上所述,content://LiB.cprovider.myprovider.Users/User/21所代表的URI的意思为:标识LiB.cprovider.myprovider中Users表中_ID为21的User项。

4.ContentProvider中公开的几个方法

public boolean onCreate():该方法在ContentProvider创建后就会被调用,Android系统运行后,ContentProvider只有在被第一次使用它时才会被创建。
public Uri insert(Uri uri, ContentValues values):外部应用程序通过这个方法向 ContentProvider添加数据。
uri——标识操作数据的URI
values——需要添加数据的键值对
public int delete(Uri uri, String selection, String[] selectionArgs):外部应用程序通过这个方法从 ContentProvider中删除数据。
uri——标识操作数据的URI
selection——构成筛选添加的语句,如”id=1” 或者 “id=?”
selectionArgs——对应selection的两种情况可以传入null 或者 new String[]{“1”}
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):外部应用程序通过这个方法对 ContentProvider中的数据进行更新。
values——对应需要更新的键值对,键为对应共享数据中的字段,值为对应的修改值
其余参数同delete方法
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):外部应用程序通过这个方法从ContentProvider中获取数据,并返回一个Cursor对象。
projection——需要从Contentprovider中选择的字段,如果为空,则返回的Cursor将包含所有的字段。
sortOrder——默认的排序规则
其余参数同delete方法    
public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。
如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有user记录的Uri为content:// LiB.cprovider.myprovider.Users /User,那么返回的MIME类型字符串应该为:”vnd.android.cursor.dir/user”。
如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为21的user记录,Uri为content:// LiB.cprovider.myprovider.Users /User/21,那么返回的MIME类型字符串为:”vnd.android.cursor.item/user”。

5.如何公开数据?

首先,继承ContentProvider并重写它的几个抽象方法
package LiB.cprovider;

import java.util.HashMap;

import LiB.cprovider.Users.User;
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.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class myprovider extends ContentProvider {

private DBHelper dbHelper;private static final UriMatcher uriMatcher;private static final int USER = 1;private static final int USER_ID = 2;private static HashMap<String, String> maps;static {    // 当没有匹配成功是时,返回NO_MATCH的值    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);    // 匹配Users表中的所有User,匹配成功后返回USER整数值

// content://LiB.cprovider.myprovider.Users/User
uriMatcher.addURI(Users.AUTHORITY, “User”, USER);
// 匹配Users表中指定ID的User项,匹配成功后返回USER_ID整数值
// content://LiB.cprovider.myprovider.Users/User/21
uriMatcher.addURI(Users.AUTHORITY, “User/#”, USER_ID);

    maps = new HashMap<String, String>();    maps.put(User._ID, User._ID);    maps.put(User.NAME, User.NAME);    maps.put(User.SEX, User.SEX);    maps.put(User.AGE, User.AGE);}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {    SQLiteDatabase db = dbHelper.getWritableDatabase();    int count = 0;    switch (uriMatcher.match(uri)) {    case USER:        count = db.delete(DBHelper.DATATABLE_NAME, selection, selectionArgs);        break;    case USER_ID:        String noteId = uri.getPathSegments().get(1);        count = db.delete(DBHelper.DATATABLE_NAME, User._ID                + "="                + noteId                + (!TextUtils.isEmpty(selection) ? " AND (" + selection                        + ')' : ""), selectionArgs);        break;    default:        throw new IllegalArgumentException();    }    this.getContext().getContentResolver().notifyChange(uri, null);    return count;}@Overridepublic String getType(Uri uri) {    return null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {    SQLiteDatabase db = dbHelper.getWritableDatabase();    // User.NAME不能为空    long _id = db.insert(DBHelper.DATATABLE_NAME, User.NAME, values);    if (_id > 0) {        Uri uri1 = ContentUris.withAppendedId(User.CONTENT_URI, _id);        this.getContext().getContentResolver().notifyChange(uri1, null);        return uri1;    }    return null;}@Overridepublic boolean onCreate() {    dbHelper = new DBHelper(this.getContext());    return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,        String[] selectionArgs, String sortOrder) {    SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();    switch (uriMatcher.match(uri)) {    case USER:        sqb.setTables(DBHelper.DATATABLE_NAME);        sqb.setProjectionMap(maps);        break;    case USER_ID:        sqb.setTables(DBHelper.DATATABLE_NAME);        sqb.setProjectionMap(maps);        sqb.appendWhere(User._ID + "=" + uri.getPathSegments().get(1));        break;    default:        throw new IllegalArgumentException();    }    SQLiteDatabase db = dbHelper.getReadableDatabase();    Cursor cursor = sqb.query(db, projection, selection, selectionArgs,            null, null, null);    cursor.setNotificationUri(getContext().getContentResolver(), uri);    return cursor;}@Overridepublic int update(Uri uri, ContentValues values, String selection,        String[] selectionArgs) {    SQLiteDatabase db = dbHelper.getWritableDatabase();    int count;    switch (uriMatcher.match(uri)) {    case USER:        count = db.update(DBHelper.DATATABLE_NAME, values, selection,                selectionArgs);        break;    case USER_ID:        String noteId = uri.getPathSegments().get(1);        count = db.update(DBHelper.DATATABLE_NAME, values, User._ID                + "="                + noteId                + (!TextUtils.isEmpty(selection) ? " AND (" + selection+ ')' : ""), selectionArgs);        break;    default:        throw new IllegalArgumentException();    }    getContext().getContentResolver().notifyChange(uri, null);    return count;}

}

6.怎么操作我自己的数据呢?

为了方便我们操作ContentProvider,Android系统为我们提供了ContentResolver类。我们可以使用getContentResolver()方法返回一个ContentResolver对象,并使用它与ContentProvider对应的方法来进行操作。

总结 

其实在Android中,系统已经为我们提供了许多的ContentProvider了,我们通常情况下是不需要去自定义ContentProvider的。但是,为了更好的理解ContentProvider,自己来实现一个ContentProvider是非常必要的。

原创粉丝点击