ContentProvider内容提供者
2016-03-20 19:34
645 查看
(一)ContentProvider内容提供者,四大组件之一。
ContentProvider是不同应用程序之间进行数据交换的标准API,ContentProvier以某种Uri的形式对外提供数据,允许其它应用访问或修改数据,其它应用程序使用ContentResolver根据Uri去访问操作 指定数据。即ContentProvider把私有数据暴露给其他应用,通常,是把私有数据库的数据暴露给其它应用的。ContentProvider只是提供数据的访问接口,是个抽象类。
开发ContentProvider的步骤:
(1)定义自己的ContentProvider类,该类需要继承ContentProvider基类。
(2)在AndroidMainfest.xml文件中注册这个ContentProvier,注册时需要为它绑定一个Uri。
自定义的ContentProvider还需要提供如下几个方法:
public boolean onCreate():该方法在ContentProvider创建后被调用,当其他应用程序第一次访问ContentProvider时,该ContentProvider会被创建出来,并立即回调该onCeate()方法。
public Uri insert(Uri uri,ContentValues values); 根据Ur插入values对应的数据。
public int delete(Uri uri, String selection,String[] selectionArgs):根据Uri删除selection条件所匹配的全部记录。
public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs): 根据Uri修改selection条件所匹配的全部记录。
public Cursor query(UrI uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) 根据Uri查询出selection条件所匹配的全部记录,其中projection就是一个列名列表,表明只选择出指定的数据列。
public String getType(Uri uri) 该方法用于返回当前Uri所代表的数据的MIME类型。如果Uri对应的数据可能包括多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么MimE类型字符串应该以vnd.android.cursor.item/开头.
(二)Uri简介
ContentProvider 要求的Uri格式为:content://org.crazyit.providers.dictprovider/words
解释: content:// :这个部分是Android的ContentProvider规定的,就像上网的协议默认是http:// 一样。暴露ContentProvider、访问ContentProvider的协议默认是content:// 。
org.crazyit.providers.dictprovider: 这个部分是ContentProvider的authorities(就相当于网站的域名)。系统就是由这个部分来找到操作哪个ContentProvider的。只要访问指定的ContentProvider,这个部分就是固定的。
words:资源部分(或者说数据部分)。当访问者需要访问不同资源时,这个部分是动态改变的。
为了将一个字符串转换成Uri,Uri工具类提供了parse()静态方法。例如:
Uri uri =Uri.parse("content://org.crazyit.providers.dictprovider/words")
(三)使用ContentResolver操作数据
通过getContentResolver():获取该应用默认的ContentResolver。
ContentResolver可调用如下方法来操作数据:
insert(Uri url,ContentValues values):向Uri对应的ContentProvider中插入values对应的数据。
delete(Uri url,Sring where,String[] selectionArgs): 删除Uri对应的ContentProvider中where提交匹配的数据。
update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri对应的ContentProvider中where提交匹配的数据。
query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) :查询Uri对应的ContentProvider中where提交匹配的数据。
(四)ContentProvider与ContentResolver的关系
不论是ContentProvider还是ContentResolver,它们提供的CRUD方法的第一个参数都是Uri,即Uri是ContentProvider和ContentResolver进行数据交换的标识。ContentResolver对指定Uri执行CRUD等数据操作,但Uri并不是真正的数据中心,这些CRUD操作会委托给该Uri对应的ContentProvider来实现。
例如:假如A应用通过ContentResolver执行CRUD操作,这些CRUD操作都需要指定Uri参数,Android系统就根据该Uri找到对应的ContentProvider(该ContentProvider属于B应用),ContentProvider则负责实现CRUD方法,完成对底层数据的增删改查,这样就可以让A应用访问,修改B应用的数据了。
ContentProvider,Uri,ContentResolver之间的关系,如下:
从图中可以看出,以指定Uri为标识,ContentResolver可以实现“间接调用”ContentProvider的CRUD方法。
(五)配置ContentProvider
Android应用要求所有应用程序组件(Activity,Service,ContentProvider,BroadcastReceiver)都必须显示进行配置
name: 指定该ContentProvider的实现类的类名
authorities:指定该ContentProvider对应的Uri(相当于给这个ContentProvider分配一个域名)
exported:指定该ContentProvider是否允许其他应用调用,如果为false,那么该ContentProvider不允许其他应用调用。
(七)监听ContentProvider的数据改变 : 内容观察者
为了在应用程序中监听ContentProvider数据的改变,需要利用Android提供的ContentObserver基类。监听ContenProvider数据改变的监听器需要继承ContentObserver类,并重写该基类所定义的onChange(boolean selfChange)方法,当它所监听的ContentProvider数据发送改变时,该onChange()方法将会触发。
为了监听ContentProvider数据的改变,需要通过ContentResolver向指定Uri注册ContentObserver几监听器。ContentProvider提供如下方法来注册监听器
registerContentObserver(Uri uri, boolean notifyForDescendents,ContentObserver oberver)
说明:
uri:该监听器所监听的ContentProvider的Uri.
notifyForDescendents: 若为ture,则精确匹配,只要以content://sms开头的uri的数据改变,都能收到通知,比如content://sms/inbox/
若为false,则不是精确匹配。
observer: 监听器实例。
例如:为指定Uri注册监听器
getContentResolver().registerContentObserver(Uri.parse("content://sms"),true,new SmsObserver(new Handler()));
SmsObserver就是ContentObserver的子类。
代码如下:
注意: 要授予本应用读取短信的权限:
<user-permission android:name="android.permission.REAT_SMS" />
ContentProvider是不同应用程序之间进行数据交换的标准API,ContentProvier以某种Uri的形式对外提供数据,允许其它应用访问或修改数据,其它应用程序使用ContentResolver根据Uri去访问操作 指定数据。即ContentProvider把私有数据暴露给其他应用,通常,是把私有数据库的数据暴露给其它应用的。ContentProvider只是提供数据的访问接口,是个抽象类。
开发ContentProvider的步骤:
(1)定义自己的ContentProvider类,该类需要继承ContentProvider基类。
(2)在AndroidMainfest.xml文件中注册这个ContentProvier,注册时需要为它绑定一个Uri。
自定义的ContentProvider还需要提供如下几个方法:
public boolean onCreate():该方法在ContentProvider创建后被调用,当其他应用程序第一次访问ContentProvider时,该ContentProvider会被创建出来,并立即回调该onCeate()方法。
public Uri insert(Uri uri,ContentValues values); 根据Ur插入values对应的数据。
public int delete(Uri uri, String selection,String[] selectionArgs):根据Uri删除selection条件所匹配的全部记录。
public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs): 根据Uri修改selection条件所匹配的全部记录。
public Cursor query(UrI uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) 根据Uri查询出selection条件所匹配的全部记录,其中projection就是一个列名列表,表明只选择出指定的数据列。
public String getType(Uri uri) 该方法用于返回当前Uri所代表的数据的MIME类型。如果Uri对应的数据可能包括多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么MimE类型字符串应该以vnd.android.cursor.item/开头.
(二)Uri简介
ContentProvider 要求的Uri格式为:content://org.crazyit.providers.dictprovider/words
解释: content:// :这个部分是Android的ContentProvider规定的,就像上网的协议默认是http:// 一样。暴露ContentProvider、访问ContentProvider的协议默认是content:// 。
org.crazyit.providers.dictprovider: 这个部分是ContentProvider的authorities(就相当于网站的域名)。系统就是由这个部分来找到操作哪个ContentProvider的。只要访问指定的ContentProvider,这个部分就是固定的。
words:资源部分(或者说数据部分)。当访问者需要访问不同资源时,这个部分是动态改变的。
为了将一个字符串转换成Uri,Uri工具类提供了parse()静态方法。例如:
Uri uri =Uri.parse("content://org.crazyit.providers.dictprovider/words")
(三)使用ContentResolver操作数据
通过getContentResolver():获取该应用默认的ContentResolver。
ContentResolver可调用如下方法来操作数据:
insert(Uri url,ContentValues values):向Uri对应的ContentProvider中插入values对应的数据。
delete(Uri url,Sring where,String[] selectionArgs): 删除Uri对应的ContentProvider中where提交匹配的数据。
update(Uri uri,ContentValues values,String where,String[] selectionArgs):更新Uri对应的ContentProvider中where提交匹配的数据。
query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) :查询Uri对应的ContentProvider中where提交匹配的数据。
(四)ContentProvider与ContentResolver的关系
不论是ContentProvider还是ContentResolver,它们提供的CRUD方法的第一个参数都是Uri,即Uri是ContentProvider和ContentResolver进行数据交换的标识。ContentResolver对指定Uri执行CRUD等数据操作,但Uri并不是真正的数据中心,这些CRUD操作会委托给该Uri对应的ContentProvider来实现。
例如:假如A应用通过ContentResolver执行CRUD操作,这些CRUD操作都需要指定Uri参数,Android系统就根据该Uri找到对应的ContentProvider(该ContentProvider属于B应用),ContentProvider则负责实现CRUD方法,完成对底层数据的增删改查,这样就可以让A应用访问,修改B应用的数据了。
ContentProvider,Uri,ContentResolver之间的关系,如下:
从图中可以看出,以指定Uri为标识,ContentResolver可以实现“间接调用”ContentProvider的CRUD方法。
(五)配置ContentProvider
Android应用要求所有应用程序组件(Activity,Service,ContentProvider,BroadcastReceiver)都必须显示进行配置
<application> <provider //注册一个ContentProvider android:name="com.xrj.dictprovider.DictProvider" android:authorities="org.crazyit.providers.dictprovider" android:exported="true" /> </application>配置时有如下属性:
name: 指定该ContentProvider的实现类的类名
authorities:指定该ContentProvider对应的Uri(相当于给这个ContentProvider分配一个域名)
exported:指定该ContentProvider是否允许其他应用调用,如果为false,那么该ContentProvider不允许其他应用调用。
(七)监听ContentProvider的数据改变 : 内容观察者
为了在应用程序中监听ContentProvider数据的改变,需要利用Android提供的ContentObserver基类。监听ContenProvider数据改变的监听器需要继承ContentObserver类,并重写该基类所定义的onChange(boolean selfChange)方法,当它所监听的ContentProvider数据发送改变时,该onChange()方法将会触发。
为了监听ContentProvider数据的改变,需要通过ContentResolver向指定Uri注册ContentObserver几监听器。ContentProvider提供如下方法来注册监听器
registerContentObserver(Uri uri, boolean notifyForDescendents,ContentObserver oberver)
说明:
uri:该监听器所监听的ContentProvider的Uri.
notifyForDescendents: 若为ture,则精确匹配,只要以content://sms开头的uri的数据改变,都能收到通知,比如content://sms/inbox/
若为false,则不是精确匹配。
observer: 监听器实例。
例如:为指定Uri注册监听器
getContentResolver().registerContentObserver(Uri.parse("content://sms"),true,new SmsObserver(new Handler()));
SmsObserver就是ContentObserver的子类。
代码如下:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 为 content://sms的数据改变注册监听器 getContentResolver().registerContentObserver(Uri.parse("content://sms"),true, new SmsObserver(new Handler())); } //提供自定义的ContentObserver监听器类 private final class SmsObserver extends ContentObserver{ public SmsObserver(Handler handler) { super(handler); } public void onChange(boolean selfChange){ //查询发送箱中的短信 Cursor cursor = getContentResolver().query(Uri.parse("content://sms//outbox"), null,null,null,null); //遍历查询得到的结果集,即可获取用户正在发送的短信 while(cursor.moveToNext()){ StringBuilder sb = new StringBuilder(); //获取短信的发送地址 sb.append("address=").append(cursor.getString(cursor.getColumnIndex("address"))); //获得短信的标题 sb.append(";subject=").append(cursor.getString(cursor.getColumnIndex("subject"))); //获得短信的内容 sb.append(";body=").append(cursor.getString(cursor.getColumnIndex("body"))); //获取短信的发送时间 sb.append(";time=").append(cursor.getLong(cursor.getColumnIndex("date"))); System.out.println("发送短信:"+sb.toString()); } } } }
注意: 要授予本应用读取短信的权限:
<user-permission android:name="android.permission.REAT_SMS" />
相关文章推荐
- php curl post 上传文件流
- ThinkPHP 数据库操作 统计查询
- 关于PHP中的引用以及clone详解
- PHPCMS V9 采集实例
- Thinkphp-事务处理
- phpmyadmin4.1.4安装配置教程
- PHP中的12个魔术方法
- PHP共享内存实现的消息队列
- ThinkPHP CURD操作
- PHP之页面跳转
- 构建自己的PHP框架--创建组件的机制
- ByteArrayOutputStream 理解
- ftp从虚拟机传输数据到开发板
- 使用ntpdate更新系统时间
- PHP zend 常用快捷键汇总
- Passed Zend Certified PHP Engineer Examination
- 【Yii2.0.7】 ./yii migrate 执行数据库迁移时出现2002错误的解决方法!
- PHP数组的相关处理函数1
- Yii获取当前域名
- 安装composer slim(php web api micro services)