记android学习之路----ContentProvider

什么是ContentProvider?

    1:内容提供者,通过ContentProvider可以在应用之间彼此访问数据,是and推荐的标准的应用之间访问数据的统一接口;
    2:大致有两种应用;通过ContentResolver访问系统或者其他应用的数据,通过自定义contentprovider向外提供数据;
    3:访问原理:使用ContentResolver的CURD方法;通过目标ContetnProvider提供的uri来操作数据;
    4:Uri:contentProvider向外提供的一个访问数据的资源标识符;可以通过该URL对其ContentProvider的数据进行操作;

URI:
1:URI:
URI由四部分组成:content://com.example.ContentProvider_name/table_name/id;
content://:标志部分;说明这个uri指向一个contentProvider;
com.example.ContentProvider_name:URI标识;指向一个确定的ContentProvider;由包名和类名组成,且必须全部小写;
table_name:路径:有可能是表的名字;也可根据录的ID;具体业务自定义;如果是XML文件的话就是一级节点/二级节点/以此类推;
id:标识需要操作的字段;
2:URI操作:
2.1 URI的转换:
Uri uri = Uri.prase(“String”);
//String=content://com.example.ContentProvider_name/table_name/id
2.2:注册URI:
常用的uri模式有两种:
//获取全部数据
content://com.example.ContentProvider_name/table_name/
//获取某条数据
content://com.example.ContentProvider_name/table_name/#
在自定义contentProvider中;我们需要根据传来的uri来判断需要操作哪一个数据表以及执行那种操作,就需要对uri进行匹配;
此时就要用到UriMatcher了:
具体操作如下:(对query,insert,delete,update)都要有这个匹配过程

        // 创建UriMatcher对象:
        1:UriMatcher urimatcher = new UriMatcher(UriMatcher.NO_MATCH);
        // 添加uri字符串,和返回码;到时候传来的uri就会在添加的这几个uri中匹配
        2:
            urimatcher.addUri("权限","路径",int 返回码);
            urimatcher.addUri("com.example.ContentProvider_name","table_name1", 0);
            urimatcher.addUri("com.example.ContentProvider_name","table_name1/id", 1);
            urimatcher.addUri("com.example.ContentProvider_name","table_name2", 2);
            urimatcher.addUri("com.example.ContentProvider_name","table_name2/id", 3);
    // 进行返回码匹配以确定正在请求哪个数据
        3:switch(urimatcher.match(Uri uri)){
            case 0:
                //操作table_name1,取出全部数据;
            break;
            case 1:
                //操作table_name1,取出指定数据;
            break;
            case 2:
                //操作table_name2,取出全部数据;
            break;
            case 3:
                //操作table_name2,取出指定数据;
            break;
            default:
                Log.i("urimatch","全不匹配");
            break;
        }

    2.3:操作URI的参数部分;
        ContentUris用于操作Uri路径后面的ID部分:
        //追加ID:
        Uri uri = Uri.prase(content://com.example.ContentProvider_name/table_name/?)
        Uri uris = ContentUris.withAppendId(uri,10);

        // 获取ID:
        Uri uri = Uri.prase(content://com.example.ContentProvider_name/table_name/10)
        int id = ContentUris.parseId(uri);
        //获取表名和id
        Uri uri = Uri.prase(content://com.example.ContentProvider_name/table_name/id)
        string table_name = uri.getPathSegments(uri).get(0)   得到table_name
        int id = uri.getPathSegments(uri).get(1)   得到id;

自定义ContetnProvider:

4:ContentProvider提供器的实现及使用:
    1:创建ContetnProvider:
        //ContentProvider是一个抽象类;需要声明一个类继承该抽象类,并全部实现其六个方法
        Public class MyProvider extends ContetnProvider{

            /**
             * 在通过ContetnResolver访问该内容提供器的时候才会调用;
             * 返回true表示初始化成功,返回false表示初始化失败;
             */
            public boolean onCreat(){
                return true;
            }

            /**
             * uri                  确定要操作哪一张表
             * projection           确定查询那些列
             * selection            类似于where条件
             * selectionArgs        条件参数
             * sortOrder            排序
             * discription          该方法供外部应用执行查询操作获取数据,返回Cursor对象
             */
            Public Uri query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

            /**
             * uri                  确定要操作哪一张表
             * selection            类似于where条件
             * selectionArgs        条件参数
             * 该方法供外部应用删除数据,返回被删除的行数
             */
            public int delete(Uri uri, String selection, String[] selectionArgs):


            /**
             * uri                  确定要操作哪一张表
             * values               要更新的数据          
             * selection            类似于where条件
             * selectionArgs        条件参数
             * 该方法供外部应用更新数据;返回受影响的行数
             */
            public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs){}


            /**
             * uri                  确定要操作哪一张表
             * values               要插入的数据
             * 该方法供外部应用向ContentProvider填入数据;操作成功后返回一个URI,表示这条新纪录
             */
            public Uri insert(Uri uri,ContentValues values){};

            /**
             *  discription 供外部应用程序获取URI的MIME类型
             * 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头
             * 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,
             */
            public String getType(){}

        }
    1:对于以上几个方法必须都要有实现;
    2:增删改查以及获取uri类型的方法中都要通过UriMatcher判断之后操作;
    3:ContentProvider只负责实现操作数据的具体方法,对数据的操作则是通过ContetnResolver来实现的:具体如下:

通过ContentResolver来操作数据:

1:创建ContentResolver实例:
        1:ContentResolver contextResolver = context.getContentResolver();
2:创建uri:
        //创建uri的目的就是为了找到目标ContentProvider,并传入需要操作的表名;在sqlite中则是直接传入表名的;
        Uri uri = Uri.prase(content://com.example.ContentProvider_name/table_name);
3:使用ContentResolver进行数据的增删改查;
    ContetnResolver提供的CURD方法和ContetnProvider提供的方法是一样的;
    插入一条数据:insert(Uri uri,ContentValues values)
    删除数据:delete(Uri uri, String selection, String[] selectionArgs)
    更新一条数据:update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
    查新数据:query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

????Contetnprovider的监听问题
????Contetnprovider的权限问题

4:监听ContentProvider的变化:
        1:ContentResolver cr = getContentResolver();
        2:cr.ontifyChange(uri,null);
        3:对于需要监听的访问者:
            1:当数据发生变化的时候就会调用ContentObserver的onChange()方法
            2:ContentResolver cr = getContentResolver();
                cr.registerContentObserver(uri,true,new MyObserver(new Handler()));
                public class MyObserver extends ContentObserver{
                    public MyObserver (Handler handler){
                        super(Handler);
                    }

                    public onChange(Boolean change){
                            if(change == true){
                                //处理代码;
                            }
                    }
                }
6:使用ContentResolver访问系统数据:
    1:获取联系人信息:
        注:ContactsContract.CommonDataKinds.Phone:是对联系人操作所封装的类:通过调用一系列常量可以获取具体字段的值;
        string sql = 'ContactsContract.CommonDataKinds.Phone';

        Cursor cursor = getContentResolver().query(sql+CONTENT_URI,NULL,NULL,NULL,NULL);
        while(cursor.moveToNext()){
            //获取联系人姓名
            string user_name = cursor.getString(cursor.getColumnIndex(sql+DISPLAY_NAME));
            //获取联系人号码:
            string user_name = cursor.getString(cursor.getColumnIndex(sql+NUMBER));
        }

    1:查看联系人存储数据库:
        http://www.cnblogs.com/luxiaofeng54/archive/2011/03/15/1985183.html
    2:联系人信息获取:
        http://www.cnblogs.com/3dant/archive/2010/12/08/1900634.html
    常见的常量:
        NUMBER:联系人号码
        DSIPLAY_NAME:联系人姓名;

        1:创建Uri:
            Uri getSystenData = Uri.prase("content://media/internal/images");
            一般只需要指定到表名就可以了,具体的行,字段等在查询函数中设置;
            例如以下uri:
            content://media/internal/images  这个URI将返回设备上存储的所有图片
            content://contacts/people/  这个URI将返回设备上的所有联系人信息
            content://contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录)

实例:
1:自定义ContentProvider,并通过ContentResolver操作;
2:通过ContentResolver操作系统数据(电话薄)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值