一、Uri的含义在Android中,为了使用数据集中管理模式,使用了ContentProvider来进行数据管理,在使用ContentProvider进行数据交互时就需要用到Uri。为了让客户端程序能够使用你的数据,你必须要定义一个公开的Uri,它由一些固定格式的文字组成,可以分成下面几个部分:
A: schema,表达的意思是使用ContentProvider来处理信息。
B: authority,一个唯一的标识符。
C: path,一般用来表示请求需要获取的是哪种类型的数据(确定MIME类型的功能)。(
MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。)
D: id,确定对应类型的数据中的哪条记录。
schema
一个标准的URI前缀,它用来指示Android必须从ContentProvider中挑出一个来处理这个URI。
authority
一个唯一的标识符,标示这个URI需要查找的ContentProvider是由哪个组织开发的,一般用跟java包命名规范相似的方式来署名这个开发组织。如果是Android内置的provider,则这个authority可以省略掉,否则authority是必须的,Google建议使用用户自定义的继承ContentProvider的类的全名来作为这个ContentProvider所要处理的URI的authority。
path
ContentProvider根据这个路径信息来判断要返回什么类型的数据,所以这个后缀路径可以自由定义。如果一个ContentProvider能查询返回很多种不同类型的数据,URI后缀要设置不同类型的数据所对应不同的URI后缀如内置的Contact ContentProvider就是用来处理名片夹,它可以返回很多种类型的数据:联系人、电话、联系方式等。所以对应这些不同类型的数据就有不同的URI后缀匹配,而且我们要为不同的数据类型设置不同的MIME类型。
id
用于确定对应类型或对应路径的数据中的哪条记录。
返回单条数据:
(1)content://contacts/people/1
返回一个人员,MIME类型是:vnd.android.cursor.item/person。
(2)content://contacts/people/1/phone/3
返回一个电话号码,MIME类型是:vnd.android.cursor.item/phone。
返回多条数据:
同时ContentProvider不仅可以返回单条数据,也可能以目录的形式返回多条数据。以上面2个URI来说,后缀的结尾都是数字,这表示查询对应某条记录,所以返回的数据是单条的,而如果是查询目录的形式就要去掉后面的数字如:
(1)content://contacts/people/
返回所有联系人,MIME类型是:vnd.android.cursor.dir/person。
(2)content://contacts/people/1/phone
返回电话号码,MIME类型是:vnd.android.cursor.dir/phone。
路径的构建:
路径(path)的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段:person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.provider.personprovider/person")
二、Uri的相关操作:因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。
UriMatcher
UriMatcher类用于匹配Uri,它的用法如下:
首先第一步,初始化:
- UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
第二步注册需要的Uri:
- matcher.addURI("com.yfz.Lesson", "people", PEOPLE);
- matcher.addURI("com.yfz.Lesson", "person/#", PEOPLE_ID);
第三部,与已经注册的Uri进行匹配:
- Uri uri = Uri.parse("content://" + "com.yfz.Lesson" + "/people");
- int match = matcher.match(uri);
- switch (match)
- {
- case PEOPLE:
- return "vnd.android.cursor.dir/people";
- case PEOPLE_ID:
- return "vnd.android.cursor.item/people";
- default:
- return null;
- }
match方法匹配后会返回一个匹配码Code,即在使用注册方法addURI时传入的第三个参数。
上述方法会返回"vnd.android.cursor.dir/person".
总结:
--addURI方法的第二个参数开始时不需要"/", 否则是无法匹配成功的。
--常量 UriMatcher.NO_MATCH 表示不匹配任何路径的返回码
--# 号为通配符
--* 号为任意字符
ContentUris
ContentUris 类用于获取Uri路径后面的ID部分
(1)为路径加上ID: withAppendedId(uri, id)
- Uri uri = Uri.parse("content://com.yfz.Lesson/people")
通过withAppendedId方法,为该Uri加上ID
- Uri resultUri = ContentUris.withAppendedId(uri, 10);
最后resultUri为: content://com.yfz.Lesson/people/10
(2)从路径中获取ID: parseId(uri)
- Uri uri = Uri.parse("content://com.yfz.Lesson/people/10")
- long personid = ContentUris.parseId(uri);
最后personid 为 :10
转自: