Android学习笔记ContentProvider

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);
}

@Override
public 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;
}

@Override
public String getType(Uri uri) {
    return null;
}

@Override
public 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;
}

@Override
public boolean onCreate() {
    dbHelper = new DBHelper(this.getContext());
    return true;
}

@Override
public 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;
}

@Override
public 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是非常必要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值