ContentProvider内容提供者

(一)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)都必须显示进行配置

   <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" />










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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值