一、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
轉自: