android内容提供者以及观察者

内容提供者

内容提供器作为Android四大组建之一.感觉没啥太大用途.

感觉就是一个应用程序创建一个可以被别的程序访问的数据库

访问其他程序中的数据

如果想要访问别的内容提供器中的共享数据,就要借助ContentResolver类,可以通过Context中的getContentResolver方法得到,它提供了一些列对数据的crud操作,操作和sqlitedatabase很相似,但是ContentResolver没有库和表,而是用一个uri代替,如'content://com.xxx.xxxx.xxx/aaa'表示访问包名是com.xxx.xxxx.xxx程序的aaa表,然后进行curd操作

查询:

getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);
//uri:看上面
//projection 指定的列名,相当于select的列名
//selection 查询条件,相当于where语句
//selectionArgs 查询条件中?的参数
//sortOrder 排序条件

返回的是一个cursor结果集,和sqlite用法一样

查询手机上所有的联系人

cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
if(cursor!=null){
    while(cursor.moveToNext()){
        Log.d(TAG, "onCreate: "+cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
        Log.d(TAG, "onCreate: "+cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
    }
}

其中的参数都是系统预设的


查询手机上电话为10086的联系人的名字

Cursor cursor = null;
try{
    cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME},ContactsContract.CommonDataKinds.Phone.NUMBER+" = ?",new String[]{"10086"},null);
    if(cursor!=null){
        //找到了这个联系人
        while(cursor.moveToNext()){
            Log.d(TAG, "onCreate: "+cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
        }
    }else{
        //没找到这个联系人
    }
}catch (Exception e){
    e.printStackTrace();
}

插入联系人(参考)

addContact("zhangphil", "12345678901","asdf@aa.com");
// 一个添加联系人信息的例子
public void addContact(String name, String phoneNumber,String email) {
    // 创建一个空的ContentValues
    ContentValues values = new ContentValues();

    // 向RawContacts.CONTENT_URI空值插入,
    // 先获取Android系统返回的rawContactId
    // 后面要基于此id插入值
    Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);
    long rawContactId = ContentUris.parseId(rawContactUri);
    values.clear();

    values.put(Data.RAW_CONTACT_ID, rawContactId);
    // 内容类型
    values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
    // 联系人名字
    values.put(StructuredName.GIVEN_NAME, name);
    // 向联系人URI添加联系人名字
    getContentResolver().insert(Data.CONTENT_URI, values);
    values.clear();

    values.put(Data.RAW_CONTACT_ID, rawContactId);
    values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
    // 联系人的电话号码
    values.put(Phone.NUMBER, phoneNumber);
    // 电话类型
    values.put(Phone.TYPE, Phone.TYPE_MOBILE);
    // 向联系人电话号码URI添加电话号码
    getContentResolver().insert(Data.CONTENT_URI, values);
    values.clear();

    values.put(Data.RAW_CONTACT_ID, rawContactId);
    values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
    // 联系人的Email地址
    values.put(Email.DATA, email);
    // 电子邮件的类型
    values.put(Email.TYPE, Email.TYPE_HOME);
    // 向联系人Email URI添加Email数据
    getContentResolver().insert(Data.CONTENT_URI, values);
}

内容观察者

内容观察者就是要观察一个uri,当这个uri下内容发生改变的时候执行的操作,类似于数据库的触发器

内容观察者要继承ContentObserver类,有一个handler参数用于多线程更新UI

主要方法是onChange(boolean self) 这个方法是当观察的uri发生改变的时候调用的方法


注册内容观察者

getContentResolver().registerContentObserver(uri,notifyForDescendents,ContentResolver);

uri是要监听的地址uri

notifyForDescendents表示是否模糊匹配,例如一个uri为aa.bb.cc/dd,当notifyForDescendents为true的时候即模糊匹配,此时aa.bb.cc/ff发生变化时也会触发此观察者

为false时只有aa.bb.cc/dd发生变化时触发

ContentResolver是内容观察者对象


注销内容观察者

getContentResolver().unregisterContentObserver(ContentResolver);

不多bb


创建内容观察者

public class MyContentResolver extends ContentObserver {
    public MyContentResolver(Handler handler) {
        super(handler);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Log.d("onChange: ","发生了变化");
    }
}


xwm

还是一个菜鸟


Comments are closed.