ContentProvider和ContentResolver的使用

ContentProvider

ContentProvider 在Android中的作用是对外共享数据,也就是说可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据进行增删改查。

ContentProvider就是自定义增删改查接口并暴露出去,让别的应用访问自己的数据。ContentProvider就是按照一定规则访问内容提供者的数据。

ContentProvider对外共享数据步骤:

1.定义一个类 继承 ContentProvider

2.定义匹配规则 Uri

3.通过静态代码块添加匹配规则

4.在manifest.xml中配置contentProvider

Uri介绍

uri代表了要操作的数据

上面我们提到了Android提供内容的加Provider,那么在Android中怎么区分各个Provider

Uri作为唯一的标识来标识这个Provider

ContentProvider的scheme为:content://

Authority用于唯一标识这个ContenProvider,外部调用者可以根据这个标识来找到它。

路径(path)可以用来表示我们要操作的数,路径的构建应根据业务而定,如下:

要操作file表中id为10的记录,可以构建这样的路径:file/10

要操作file表中id为10的记录的name字段,路径:file/10/name

要操作file表中的所有记录,可以构建这样的路径:/file

当然要操作的数据可以是数据库,也可以是文件、xml或者网络等其他存储方式。

代码示例:

public class FileProvider extends ContentProvider {

    private Context mContext;

    private static final int QUEYSUCESS = 0;

    private static final int INSERTSUCESS = 1;

    //UriMatcher.NO_MATCH表示不匹配任何路径的返回码

    private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private SQLiteDatabase mDb;

    private String mTableName = DbOpenHelper.STUDENT_TABLE_NAME;

    static{

        //注册所有要匹配的uri

        mUriMatcher.addURI("com.itcast.contentp.FileProvider", "query", QUEYSUCESS);

        mUriMatcher.addURI("com.itcast.contentp.FileProvider", "insert", INSERTSUCESS);

    }

    //该方法在其它应用第一次访问它时才会被创建

    @Override

    public boolean onCreate() {       

        mContext = getContext();

        mDb = new DbOpenHelper(mContext).getWritableDatabase();

        return false;

    }

    /**

    *public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)

    *projection : 这个参数告诉查询要返回的列(Column)即需要的字段,比如Contacts Provider提供了联系人的ID和联系人的NAME等内容.

    *selection :查询where字句

    *selectionArgs : 查询条件属性值

    *sortOrder :结果排序

    */

    @Override

    public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3,String arg4) {

        if (mUriMatcher.match(uri)== QUEYSUCESS ) {//uri匹配后进行下面的操作

            Cursor cursor = mDb.query(tableName, arg1, arg2, arg3, null, null, null);

            getContext().getContentResolver().notifyChange(uri, null);

            return cursor;

        }else{

            throw new IllegalArgumentException("match fail");

        }

}

这里只给出部分代码。。。。。。

ContenResolver

使用ContentResoler调用ContentProvider提供的接口,对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用Activity提供的getContentResolver()方法来获取ContentResolver对象。ContentResolver类提供了与ContentProvider类相同签名的四个方法:

public Uri insert(Uri uri,ContentValues values)

public int delete(Uri uri,String selection,String[] seletionArgs)

public int update(Uri uri,ContentValues values,String seletion,String[] selectionArgs)

public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder)

1.对ContentProvider中的数据进行增删改查

直接看代码:

//uriQuery必须与要查询的ContentProvider中的要操作数据的uri保持一致(btw 这里只给了查询好插入的例子)

ContentValues values = new ContentValues();

Cursor cursor = getContentResolver().query(uriQuery, null, null, null, null);

int count = cursor.getCount(); //获取到一共有多少行

int contact_id = count + 1;

ContentValues nameValues = new ContentValues();

nameValues.put("name", name);

nameValues.put("mime_type", "vnd.android.cursor.item/name");

nameValues.put("contact_id", contact_id);

getContentResolver().insert(uriInsert, nameValues);

2.监听ContentProvider中数据的变化

在ContentProvider发生数据变化时调用getContentResolver.notifyChange(uri,null)来通知注册在此URI上的访问者。当数据发生变化时会调用ContentObserver的onChange()来进行一系列的后续操作~~~

如下:

public class MainActivity extends Activity {

    private Uri uri;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //注册

        uri = Uri.parse("content://com.example.contentp.AccountProvider");

        getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()))

    }

}

监听到变化后调用onChange()来执行一系列操作

private class MyObserver extends ContentObserver {

    Uri uri = Uri.parse("content://com.example.contentp.AccountProvider");

    public MyObserver(Handler handler) {

        super(handler);

    }

    @Override

    public void onChange(boolean selfChange) {

      Cursor cursor = getContentResolver().query(uri, new String[]{"file","mime_type","date"}, null, null, null);

      while(cursor.moveToNext()){

      //执行一些操作

      }

    }

}

ContentProviderClient

与ContentResolver一样都是用来对ContentProvider中的数据进行添加、删除、修改和查询操作的

通过调用getContentPesolver().acquireContentProviderClient(activity)方法获取ContentProviderClient对象。

用法跟ContentResolver相似,不同点是ContentProviderClient对象必须在结束使用后,调用ContentProviderClient.release()来释放。这会使系统释放对应的ContentProvider对象。

对于相同ContentProvider的多次调用,推荐使用ContentProviderClient.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容