记android学习之路----ContentProvider

来源:互联网 发布:南阳网络推广哪家专业 编辑:程序博客网 时间:2024/06/04 18:10

什么是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
原创粉丝点击