四大组件(四)—content provider

一、概述

Content Provider相当于是程序与程序之间的接口。让原本不可能通信的程序,通过内容提供者这个桥梁变得可以通信。

  • 应用程序默认创建的数据库文件只有自己才能访问,其他的应用程序是不具备读写权限的。

  • 把自己应用程序的数据库文件(内容)暴露出来,给其他应用程序访问。 与AIDL不太一样,内容提供者暴露的是磁盘中的数据, aidl暴露的是内存中的数据。

二、使用条件

一般来说,我们只使用Android系统的内容提供者,但是不会写。因为目前的趋势是:没有人会把自己的数据公布出去(腾讯也不会)。即使,搞一个provider,也不一定会有人去用。

  • 一般情况下,都是系统暴露数据给第三方程序访问,很少有或者是几乎没有第三方程序暴露数据给其他的程序访问。

  • 开发的时候,更多的情况,写的都是访问内容提供者的代码,一般都是访问系统应用程序暴露出来的数据

  • 联系人应用 、短信应用 、 多媒体库

三、内容提供者的使用步骤

  1. 定义一个类 ,继承 contentProvider
    public class BackDoor extends ContentProvider {}
  2. 注册contentprovider , 要添加authorities的属性

     <!--   
     1.注册内容提供者 ,一定要声明authorities , 这个authorities 相当于是口令,来访的人必须要说出这个口令,否则内容提供者将不受理,不帮它干活。
    2.要4.3以上版本,一定要加上exporeted=true;
     -->
    <provider 
              android:name="com.sky.db.DbProvider" 
              android:exported="true"
              android:authorities="com.sky.db.BANK">
    </provider>
  3. 声明 URIMatcher ( uri 匹配器)

        /**
         * 只要谁能说对了这个口令就可以来操作内容提供者,这样实际上是不安全的,所以为了防范或者是过滤 必须要对uri进行严格的匹配,或者是叫做升级口令
         * ,密码
         */
        // 声明一个匹配器,只要来调用crud的方法,都先用这个匹配器去过滤uri , 里面给定的参数是指:如果没有匹配,那么将返回这个code
        static UriMatcher match = new UriMatcher(UriMatcher.NO_MATCH);
  4. 使用静态代码块,预设匹配规则

    // 使用静态的代码块来预设一些匹配规则,也就是给这个匹配器先制订一套规则
    static {
        // 在这里已经预设了一个匹配规则 来访的uri,必须是这样才能通过
        // content://xiaojidunmogu/huangheruhai
        // 来访必须匹配主机名 , path , 如果匹配,将返回1 , 否则将返回 -1
        //
        match.addURI("com.sky.db.BANK", "bank", 1);
        /*
         * 一般,如果要暴露多张数据表,这里必须要指定多条过滤规则 , 一般这个path都不写无意义的单词,多数情况下
         *写的是表的名字,因为这样写,外部程序可以根据名称来判定当前要访问哪一张表。
         * mather.addURI("com.sky.db.BANKK", "teacher", 2);
        mather.addURI("com.sky.db.BANK", "student", 3);
        mather.addURI("com.sky.db.BANK", "people", 4);*/
    
    }
  5. 在CRUD里面判断来访的URI是否正确

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // 假设匹配返回的code 是1 ,
        if (mather.match(uri) == 1) {
            Log.d(TAG, "delete---");
            //操作数据库... 假设这个应用的数据库里面有10张表。   student  , teacher  ,people  ,data ,address
    
            DbHelper helper = new DbHelper(getContext());
    
            SQLiteDatabase db = helper.getWritableDatabase();
    
            //执行删除的方法,注意:这里的参数多半都是由外部程序传递进来的,我们一般不自己定义。 
            db.delete("account", selection, selectionArgs);
        } else {
            throw new IllegalArgumentException("uri错误,请检查。。。");
        }
        // int result = mather.match(uri);
        return 0;
    }
  6. 在其他应用程序通过内容解析者操作内容提供者

    public void insert(View v){
        //其他应用程序使用contentprovider 暴露API接口,供其他人访问。
        // 如果想操作contentprovider,就要通过一个contentresolver , 内容解析者
        //1. 得到内容解析者
        ContentResolver resolver = getContentResolver();
    
        //2. 定义uri, 访问的口令 ,访问的路径 这里实际上给的是早前注册的口令,不过,口令前面必须加上content://
        Uri url = Uri.parse("content://com.sky.db.BANK/bank");
    
        //定义插入的数据
        ContentValues values = new ContentValues();
        values.put("name", "zhangsan");
        values.put("money", 500);
    
        //3. 操作内容提供者中的增加方法
        resolver.insert(url, values);
    }

四、内容观察者

1.观察者的概念

内容提供者在操作数据成功后,对外发出一个通知,关心这个通知的观察者就能收到通知。
getContext().getContentResolver().notifyChange(arg0, null);
其中两个参数的意义如下:
1. 属于什么样的uri对应的数据已经发生改变了
2. 内容观察者
* 如果内容观察者给null, 代表的时候数据发生改变,我就发出来一个通知,关心这个通知的人,就会收到改变的通知。
* 如果直接指定了一个对象,达标数据一旦改变,那么这个内容观察者就能收到通知

2.内容观察者使用步骤

注册一个内容观察者,观察指定的uri数据。

Uri uri = Uri.parse("content://com.sky.db.BANK/account");
//注册一个内容观察者
/**
 * 让它观察指定的uri路径,如果通过了这个uri去改变了数据库的数据,俺么后面的内容观察者将会得到通知。
 * 中间这个参数的意思是:true;只要匹配对了前半段的Uri,那么也能收到通知。false,代表全部uri,一个字母不漏,都要完全匹配,才能收到通知
 */
getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) {
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        System.out.println("来人啊,银行行长又来偷钱了..");
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值