那么我们也可以定义自己的ContentProvider来使跨应用共享数据。数据具体的存贮方式可以为数据库、文件,持久化或非持久化存储的其他形式。在这里我们还是使用sqlite数据库存贮数据吧。
老规矩,先来点基础知识。
一.基础知识
1:URI是什么?统一资源标识符,用来标识某一资源的。
通常一个Uri主要由以三部分组成:scheme、Authority、path
1.scheme:ContentProvider(内容提供者)的scheme已经由Android系统规定为:content://
2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作persion表中id为5的记录,可以构建这样的路径:/persion/5
要操作persion表中id为20的记录的name字段, persion/name/10
要操作persion表中的所有记录,可以构建这样的路径:/persion
使用Uri类中的parse()方法获取Uri: Uri uri = Uri.parse("content://com.dongzi/persion")
上面Uri的scheme: content://
Authority: com.dongzi
path: /contact
2、UriMatcher、ContentUrist和ContentResolver
Android系统提供了两个用于操作Uri的工具类:UriMatcher 和ContentUris
UriMatcher:用于匹配Uri:
代码如下 | 复制代码 |
static final int CODES=2; static final int CODE=1; static final String AUTHORITY="com.dongzi"; //授权 static final UriMatcher uriMatcher; //Uri匹配 static { //注册匹配的Uri以及返回码 uriMatcher=new UriMatcher(UriMatcher.NO_MATCH); //不匹配任何路径返回-1 uriMatcher.addURI(AUTHORITY, "persion", CODES); //匹配content://com.dongzi/persion 返回2 uriMatcher.addURI(AUTHORITY, "persion/#", CODE); //匹配content://com.dongzi/persion/1234 返回1 } |
ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
• withAppendedId(uri, id)用于为路径加上ID部分
• parseId(uri)方法用于从路径中获取ID部分
代码如下 | 复制代码 |
//为Uri添加ID Uri uri=Uri.parse("content://"+AUTHORITY+"/persion"); ContentUris.withAppendedId(uri, 1234); //生成后的Uri为:content://com.dongzi/person/1234 //获取Uri后面的ID long id=ContentUris.parseId(Uri.parse("content://com.dongzi/person/1234")); //得到ID为:1234 |
ContentResolver提供了如下主要方法:
代码如下 | 复制代码 |
@Override |
这里主要说下Url所代表数据的MIME类型:
如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,
例如:要得到所有person记录的Uri为content://com.dongzi/person,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/person"。
如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,
例如:得到id为1234的person记录,Uri为content://com.dongzi/person/1234,那么返回的MIME类型字符串为:"vnd.android.cursor.item/person"。
使用ContentResolver操作ContentProvider中的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查 询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。ContentResolver提供了ContentProvider对应的增、删、改、查方法。
监听ContentProvider中数据的变化
如果我们需要得到数据变化通知,可以使用ContentObserver对数据(数据采用uri描述)进行通知更改以及监听。
代码如下 | 复制代码 |
//通知内容以及发生改变,同时注册了内容监听,监听到内容变化,就调用onChange方法 |
二.实战
说了那么多,是时候了解ContentProvider的使用了,我们这里采用sqlite存贮数据。当然,我们直接采用联系人数据不是更好?
1:首先我们定义DBHelper继承SQLiteOpenHelper,并建表。
代码如下 | 复制代码 |
package com.dongzi; import android.content.Context; public class DBHelper extends SQLiteOpenHelper { static final String DB_NAME = "dongzi.db"; } @Override @Override } |
2:然后定义MyContentProvider继承ContentProvider,并且在类加载时候初始化UriMatcher匹配,以及授权AUTHORITY,同时,这个ContentProvider需要在AndroidManifest.xml中进行注册,并添加授权。
代码如下:
代码如下 | 复制代码 |
package com.dongzi; import android.content.ContentProvider; public class MyContentProvider extends ContentProvider { } |
如果我们基本了解了上述说的基础知识,那么这些代码不难看懂,其实也非常简单,不直接操作DBHelper类,而是通过ContentProvider间接操作,而操作ContentProvider又是太通过
ContentResolver这个类,实现不同应用都可以访问这些数据。