android_内容提供者的升级定义和访问

对于上一篇博客android_内容提供者和内容解析者_简单入门
里面所出现的问题,现在来描述一下:
1. 应用程序在发布上去的时候,会对外公布口令(以Log形式), 所以只要有人拿过来这个口令,不管是谁,都帮他干活。
2. 在代码中, 假设这个应用有100张表想暴露出去,并且刚好有100个APP来访问不同的表,那么这个时候如何分辨出,哪一个应用访问哪一个表呢? 就要根据URIMatcher来界定了。

问题出现了,怎么解决?
答案:就是使用URIMatcher来解决一下

URIMatcher是一个种匹配的规则的升级版

现在我们重新定义一下,
内容提供者应该怎么去定义:
步骤:
1. 定义一个类,继承ContentProvider
2. 注册内容提供者,要注意:要添加作者名
3. 在内容提供者里面声明URIMatcher
4. 使用静态代码块预设匹配规则
5. 在CRUD方法里面先判断uri ,如果正确,就操作数据库

步骤写好:
现在代码演示一下:

1. 定义一个类,继承ContentProvider

public class BankBackDoor extends ContentProvider {

    private static final String TAG = "BankBackDoor";

    //第三步:在内容提供者里面声明URIMatcher
    //声明了一个URI的匹配器 参数的意思是: 如果没有匹配,那么久返回这个code
    //UriMatcher.NO_MATCH就是我们常量-1
    static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

    static{
        //http://www.baidu.com/news.html;
        //content://com.itheima.bank.BACKDOOR/path
        /*
         * 参数一: 作者名
         * 参数二: path路径(一般就是写表名)
         * 参数三: 一旦匹配上了这条uri,那么久返回100匹配码
         * 
         */
        //第四步: 使用静态代码块预设匹配规则
        matcher.addURI("com.itheima.bank.BACKDOOR", "account", 100);
        matcher.addURI("com.itheima.bank.BACKDOOR", "stu", 101);
        matcher.addURI("com.itheima.bank.BACKDOOR", "teacer", 102);
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
    //第五步:在CRUD方法里面先判断uri ,如果正确,就操作数据库
        if(matcher.match(uri) == 100){
            Log.d(TAG, "insert---");
            //往account表里面添加数据
            //1 。 得到数据库帮助类对象    
            //2. 添加数据           
            BankOpenHelper helper = new BankOpenHelper(getContext());
            SQLiteDatabase db = helper.getWritableDatabase();
            db.insert("account",null, values);
            db.close();     
        }else{
            throw new IllegalArgumentException("口令错误,滚犊子..");
        }
        return null;
    }

    @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
        if(matcher.match(uri) == 100){
            Log.d(TAG, "delete---");


            BankOpenHelper helper = new BankOpenHelper(getContext());
            SQLiteDatabase db = helper.getWritableDatabase();
            db.delete("account", selection, selectionArgs);
            db.close();


            //参数一: 具体是什么位置的数据发生了改变
            //参数二:具体的内容观察者对象, 如果是null , 那么表明不告诉具体的某一个人,
            getContext().getContentResolver().notifyChange(uri, null);
        }else{
            throw new IllegalArgumentException("口令错误,滚犊子..");
        }
        return 0;
    }



    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        if(matcher.match(uri) == 100){
            Log.d(TAG, "query---");
            BankOpenHelper helper = new BankOpenHelper(getContext());
            SQLiteDatabase db = helper.getReadableDatabase();
            Cursor cursor = db.query("account", projection, selection, selectionArgs, null, null, sortOrder);
            return cursor ;
        }else{
            throw new IllegalArgumentException("口令错误,滚犊子..");
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        if(matcher.match(uri) == 100){
            Log.d(TAG, "update---");

            BankOpenHelper helper = new BankOpenHelper(getContext());
            SQLiteDatabase db = helper.getWritableDatabase();
            db.update("account", values, selection, selectionArgs);
            db.close();



            //参数一: 具体是什么位置的数据发生了改变
            //参数二:具体的内容观察者对象, 如果是null , 那么表明不告诉具体的某一个人,
            getContext().getContentResolver().notifyChange(uri, null);

        }else{
            throw new IllegalArgumentException("口令错误,滚犊子..");
        }
        return 0;
    }

    //-----------------------------

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        return false;
    }
}

第二步: 注册内容提供者,要注意:要添加作者名(口令)

<!-- authorities : 就是其他程序来访问数据的时候与我们自己的contentProvider对接的口令 -->
        <provider android:name="com.itheima.bank.BankBackDoor" 
            android:authorities="com.itheima.bank.BACKDOOR" android:exported="true"></provider>

上面的5步就可以设置好一个内容提供者了.

既然内容提供者已经升级了,那我们的内容访问者应该怎么匹配呢?

现在代码演示一下

    public void insert(View v){
        //ContentProvider 内容提供者 暴露数据
        //ContentResolver 内容解析者

        //1. 得到内容解析者对象
        ContentResolver resolver = getContentResolver();

        //到底要插入哪一个数据库的表 -- 操作内容提供者的口令
        //content:// 这个前缀必须要加上,否则对接失败
        Uri uri = Uri.parse("content://com.itheima.bank.BACKDOOR/account");

        //准备数据
        ContentValues values = new ContentValues();
        values.put("name", "aobama");
        values.put("money", 1000);


        //2. 执行insert方法
        resolver.insert(uri, values);

    }

其实需要访问升级之后的内容提供者的关键还是
Uri uri = Uri.parse(“content://com.itheima.bank.BACKDOOR/account”);
在我们最后后面,加上了,内容提供者的path(一般就是表名).
Uri匹配上了,就可以成功的访问了

提醒:
学习内容提供者的目的

  1. 在实战开发当中很少给自己的应用程序定义一个内容提供者。
  2. 理解内容提供者的工作原理,以及背后都是如何操作。
  3. 更多的情况是,我们需要访问内容提供者,当然这些内容提供者不是其他应用定义的,而是系统应用中定义的。
  4. 用的比较多的: 联系人的内容提供者 、 短信的内容提供者 、多媒体的内容提供者(image\audio\video)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值