您的位置:首页 > 编程语言 > PHP开发

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

<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" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: