Android - Content Provider
ContentProvider在android中的作用是对外共享应用的私有数据,也就是说可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对应用中的数据进行添删改查。
关于数据共享,前面的文件操作模式中知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。
那么,为何还要使用ContentProvider 对外共享数据呢?
如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式不同而不同,导致数据的访问方式无法统一,
如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据等等。
使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
成为ContentProvider
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
1 | public class PersonContentProvider extends ContentProvider{ |
第二步需要在AndroidManifest.xml 的<provider>
节点对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider,ContentProvider 采用了authority
(主机名/域名)对它进行唯一标识(详见Content URIs)
1 | <manifest .... > |
Tips:Content Provider在<provider>
节点中也可以声明一些访问的权限,当访问者没有申请到权限是不能访问provider的。
ContentProvider类主要方法
- boolean onCreate()
该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。 - Uri insert(Uri uri, ContentValues values)
该方法用于供外部应用往ContentProvider添加数据。 - int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于供外部应用从ContentProvider删除数据。 - int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于供外部应用更新ContentProvider中的数据。 - Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于供外部应用从ContentProvider中获取数据。 - String getType(Uri uri)
该方法用于返回当前Url所代表数据的MIME类型。
如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
例如:要得到所有person记录的Uri为content://net.yrom.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
例如:得到id为10的person记录,Uri为content://net.yrom.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。
Content URIs
Content Uri是一个ContentProvider的唯一标识
ContentProvider的Content Uri的scheme已经由Android所规定,为:content://
*Uri的操作见UriMatcher和ContentUris篇
##操作Provider提供的数据
当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver类来完成,可以使用Activity中getContentResolver()
方法获取ContentResolver实例。
ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
- Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。 - int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。 - int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。 - Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Content Uri
###对ContentProvider的数据进行添删改查
eg.
1 | ContentResolver resolver = getContentResolver(); |
###监听ContentProvider中数据的变化
如果ContentProvider的访问者需要知道ContentProvider中的数据发生了变化,可以在ContentProvider 发生数据变化时调用getContentResolver().notifyChange(uri, null)
来通知注册在此URI上的访问者
eg.
1 | public class PersonContentProvider extends ContentProvider { |
如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver
对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()
方法:
1 | getContentResolver().registerContentObserver( |
eg.监听用户用户的短信:
使用系统自带的短信程序发送短信时,程序会通过ContentProvider把短信保存进数据库,并且发出一个数据变化通知,使用ContentObserver对数据变化进行监听,在用户发送短信时,就会被ContentObserver监听到短信:
注册监听:
1 | getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new SmsObserver(new Handler())); |
监听类:
1 | private final class SmsObserver extends ContentObserver{ |
Author: Yrom
Link: https://yrom.net/blog/2011/12/28/android-content-provider/
License: 知识共享署名-非商业性使用 4.0 国际许可协议