一、簡介
Android使用一種稱為ContentProvider的概念來將數據抽象為服務,這種內容提供程序的理念看起來像啟用了REST的數據提供程序。
要從ContentProvider檢索數據或將數據保存到ContentProvider,需要使用一組類似REST的URI。例如,要從封裝圖書數據庫的ContentProvider獲取一組圖書,需要使用以下形式的URI:
- content://com.android.book.BookProvider/books
要從圖書數據庫獲得指定圖書(如編號為:88圖書),則要使用以下類似URI:
- content://com.android.book.BookProvider/books/88
設備上的任何應用程序都可以通過這些URI來訪問或操作數據,所以在應用程序之間的數據共享上ContentProvider扮演著非常主要的角色。
二、Android內置的ContentProvider
Android中存在大量的內置ContentProvider,他們記錄在SDK的android.provider包中,如:
Browser
Calllog
Contacts
People
Phones
Photos
Groups
MediaStore
Audio
Albums
Artists
Playlists
Images
Video
Settings
其中頂級項數據庫,較低級的項是表。所以Browser、CAllog,MediaStore和Settings都是封裝為ContentProvider的獨立SQLite數據庫.這些數據庫通常具有擴展名.db。僅能從實現包訪問,任何來自外部的訪問都要通過ContentProvider接口。
三、ContentProvider架構
與網站一樣,設備上的每個ContentProvider都會使用字符串注冊本身,這個字符串類似網站域名,但稱為:授權(Authority)。授權的注冊則AndroidManifest.xml中進行。如:
- <provider android:name="BookProvider" android:authorities="com.myCompany.BookProvider"/>
在進行了授權後,ContentProvider就擁有了以授權前綴開頭的URI:
- content://com.myCompany.BookProvider/
注意:Android內置的ContentProvider可能沒有完全限定的授權名,只有在使用第三方提供的時才使用完全限定名。這也就是為什麼有時候僅使用Contacts來引用聯系人ContentProvider。
1、Android內容URI的結構
Android中的內容URI類似於Http URL,但他們以content://開頭具有一下通用形式:
- Content://*/*/
- 或
- content://authority-name/path-segment1/path-segment2/etc......
2、Android MIME類型的結構
就像網站返回給指定URI的MIME類型一樣,ContentProvider也負責返回給URI的MIME類型。MIME類型包括兩部分:類型和子類型。如:
- text/html
- text/css
- text/xml
- application/pdf
- application/vnd.ms-excel
類型和子類型對於他們所表示的內容必須是唯一的,且如果類型和子類型不是標准的,則需要在他們前面加上vnd。
3、使用URI讀取數據
要從ContentProvider獲取數據,需要使用該ContentProvider提供的URI。
如下:為從聯系人提供程序獲取單行聯系人信息
- Uri baseUri = Contacts.People.CONTENT_URI;
- uri myPersonUri = baseUri.withAppendedPath(Contacts.People.CONTENT_URI,"80");
- Cursor cur = manageQuery(myPersonUri,null,null,null);
在上面的基礎上我們來看看,如何獲取一個游標,這個游標包含來自contactsContentProvider的People表的一組特定的列。
- String[] projection = new String[]{
- People._ID,
- People.NAME,
- People.NUMBER
- };
-
- Uri mContactsURi = Contacts.People.CONTENT_URI;
- Cursor managedCursor = managedQuery(
- projection,
- null,
- Contacts.People.NAME + "ASC"
- );
4、使用游標
在使用Android游標前,先了解一些關於游標的的知識。
游標是一個行集合;
讀取數據之前,需要使用moveToFirst(),因為游標放在第一行之前;
需要知道列的名稱和類型;
所有字段訪問都基於列編號,所以必須首先將列名稱轉換為列編號;
游標可以隨意移動;
可以使用游標獲取行計數;
使用while循環導航游標:
- if (cur.moveToFirst == false){
- return;
- }
- int nameColumnIndex = cur.getColumnIndex(People.NAME);
- String name = cur.getString(nameColumnIndex);
-
- while (cur.moveToNext()){
- //獲取屬性值
- }
使用for循環導航游標
- int nameColumn = cur.getColumnIndex(People.NAME);
- int ploneColumn = cur.getColumnIndex(People.NUMBER);
-
- for(cur.moveToFirst();!cur.isAfterLast();cur.moveToNext()){
- String name = cur.getString(nameColumn);
- String phoneNumber = cur.getString(phoneColumn);
- }