Android學習筆記(四七):Content Provider初談和Android連絡人資訊

來源:互聯網
上載者:User

Content Provider

在資料處理中,Android通常使用Content Provider的方式。Content Provider使用Uri執行個體作為控制代碼的資料封裝的,很方便地訪問地進行資料的增、刪、改、查的操作。Android並不提供所有應用共用的資料存放區,採用content Provider,提供簡單便捷的介面來保持和擷取資料,也可以實現跨應用的資料訪問。簡單地說,Android通過content Provider從資料的封裝中擷取資訊。

Content provider使用Uri的方式來定位資訊。以“content://”開頭來表明這是一個content URI。例如“content://contstans/5”,其中“content://constans”稱為base URI,相當於資料的namespace,它的結構可以更為複雜,可以有多層結構。例子中的“5”,則是具體執行個體的標識。

一般來講,Android的資料存放區有4種方式:

1、 Preferences,參見Preference的使用,通常都是索引值對(name-value pair)。
2、檔案:在手機裝置或者外設上儲存,預設的只能由建立的應用訪問。
3、資料庫(RDBMS):SQLite方式,參見SQLite的使用,由建立的應用訪問。
4、網路:Android提供API遠程在伺服器上儲存資料。

如果我們需要在應用中共用,採用Content Provider。無論資料具體的儲存方式,Content Provider提供了一個統一的介面。資料將採用類表格的方式提供,有行有列,列表示不同屬性的資料,例如電話號碼、電郵地址等。每個記錄(每行)都有一個唯一的_ID欄位來標識。在以後具體的代碼中看更直觀看出。

原生providers

Android提供一些原生的content provider,來往問系統中的視頻、映像和連絡人資訊等等。例如連絡人的URI為“content://com.android.contacts/contacts”,原生的providers一般都有定義,例如連絡人為ContactsContract.Contacts.CONTENT_URI。由於系統不同版本可能會存在差異,我們應儘可能使用系統的定義。

在android.provider的包中,可以查看原生的provider,例如有AlarmClock、Browser、CalendarContract、CallLog、ContactsContract(包括有Contacts,Groups,PhoneLookup等)、MediaStore(Audio 『Albums、Artists、Genres、Playlists』、Files、Images、Video)和Setting。

通過Content Providers讀取資訊

我們利用原生provider連絡人來看看如何來讀取資訊,連絡人的資料結構比較複雜,後面會詳細介紹,這裡我們將儘可能簡化,先對Content Provider有個直觀的認識。核心是通過managedQuery( )來擷取Cursor。Cursor實際返回是一個二維的表格,有行有列,行是具體的元素,列是該元素具體的屬性。整個方式和SQLite非常相似。

//可以很方便將Cursor的內容映射到ListActivity上,具體參見Android學習筆記(四十二):SQLite,ListView,ContextMenu
public class Chapter26Test1 extendsListActivity {
    private String[] INFO = new String[]{
        ContactsContract.Contacts._ID,
//對於Content Provider返回資料表格而言,注意唯一標識_ID通常是必須讀取的,否則很容易報錯
        ContactsContract.Contacts.DISPLAY_NAME,
        ContactsContract.Contacts.HAS_PHONE_NUMBER
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /* managedQuery( )從Content Provider讀取資料
         * 第1參數表示URI,
         * 第2參數表示所需讀取的資訊,;
         * 第3個參數是限制條件,類似SQL中的WHERE;
         * 第4個參數和第3個參數配合使用,具體支援第三個參數中的“?”具體為何;
         * 第5個參數類似於SQL中的ORDER BY */

        Cursor contactCursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO, null,null,null);
        ListAdapter adapter = new SimpleCursorAdapter(this,
                                                  R.layout.chapter_22_test1,contactCursor,
                                                  new String[]{ContactsContract.Contacts.DISPLAY_NAME,ContactsContract.Contacts.HAS_PHONE_NUMBER},
                                                  new int[]{R.id.c22_name,R.id.c22_gravity});
        setListAdapter(adapter); //偷偷懶,本例子直接利用了Android學習筆記(四十二)中SQLite例子中的xml
    }
}

說說Android連絡人資訊的組織圖及讀取

這是Android給出的連絡人群組織結構圖。分為三層。

第一層,Contact,即ContactContract.Contacts,是整合的連絡人資訊。

第二層,RawConact,即ContactContract.RawContact,記錄的是該連絡人來自某資訊源的資訊,例如本地輸入的,來自Google的,從微軟Exchange中匯出的,或則來自某個社交網站的資訊。每個RawContact記錄的資訊都來自同一資訊源。

第三層,Data,即ContactContract.Data,是具體的資訊儲存,例如記錄連絡人姓名,email資訊,家庭電話,手機電話資訊等等,每一個Data都存放一個具體的資訊。在Data中的MIME TYPE說明儲存資訊的類型。具體在ContactContract.CommonDataKinds中定義。每個Data中有DATA1-DATA15個欄位來儲存資訊,各欄位所代表的含義,也可以在CommonDataKinds中具體查到。

下面,我們一層一層地讀取連絡人資訊,將更清晰地看到這個結構。要讀取詳細資料,對於Content Privider,關鍵是Uri逐層定位,才能擷取資訊。為了清晰表述,我們將整個路徑寫出來。

第一層資訊,將返回連絡人清單中的多個Contacts,Uri為ContactsContract.Contacts.CONTENT_URI

private String[] INFO_1= new String[]{
    ContactsContract.Contacts._ID,//這是每個row,也就是每個連絡人的唯一的ID標識
    ContactsContract.Contacts.DISPLAY_NAME,
};
Cursor cursor = managedQuery(ContactsContract.Contacts.CONTENT_URI,INFO_1,null,null,null);

cursor是表格形式,每一個行表示一個連絡人。要讀取哪些列,在第二個參數String[]中定義。可以選取那些列,在Android Reference中的ContactsContract.Contacts中的Column中可以查到。最關鍵的列資訊為_ID,它是行,也就是每個連絡人的唯一標識。除此之外,每個連絡人的資訊會根據旗下的RawContact進行整合,因此,我們可以查到聯絡的名字ContactsContract.Contacts.DISPLAY_NAME等。

利用Contacts._ID,我們可以檢索第二層的資訊。

第二層資訊,將返回某連絡人的多個RawContacts

同樣,返回表格中的列,可以查看ContactsContract.RawContacts中查看。我們選取下面的資訊,此外,如果要查看資訊的來源,例如來自com.google,可通過RawContacts.ACCOUNT_TYPE和RawContacts.ACCOUNT_NAME兩個列查看。

private String[ ] INFO_2 = {
    ContactsContract.RawContacts._ID, //這是RawContact的唯一標識
    ContactsContract.RawContacts.CONTACT_ID, //這是該RawContact關聯的Contact._ID
};

通過查詢全部的RawContacts,通過條件檢索,要求連絡人的ID為指定的某連絡人。在下面的例子在managedQuery中給出了param3和param4的條件,注意參數3,如果我們有多個條件,可以用AND等邏輯符合進行表述。

Cursor cursor = managedQuery(ContactsContract.RawContacts.CONTENT_URI ,
                                                     INFO_2 ,
                                          RawContacts.CONTACT_ID + "=?" ,
                                          new String[]{String.valueOf(contactId)} ,
                                                    null);

通過RawContacts._ID,我們可以往下檢索RawContacts下面各Data的資訊內容。

第三層資訊:將返回某RawContact的各Data的資訊

可查詢各列的資訊見ContactsContract.Data的介紹。

private String INFO_3[] = {
    ContactsContract.Data._ID, //這是Data資訊塊的唯一標識
    ContactsContract.Data.CONTACT_ID, //關聯第一層資訊的CONTACT_ID
    ContactsContract.Data.RAW_CONTACT_ID, //關聯第二層資訊的RAW_IDCONTACT_ID
    ContactsContract.Data.MIMETYPE, //具體含義可查ContactsContract.CommonDataKinds
    ContactsContract.Data.DATA1, //通常讀取DATA1就可以,在具體的ContactsContract.CommonDataKinds.Phone/Email等查到DATA1-DATA15的含義
    ContactsContract.Data.DATA2,
    … …
    ContactsContract.Data.DATA15,
};

讀取的方式有兩種。

方式一:指定定具體的Uri:

Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawId);
Uri dataUri = Uri.withAppendedPath(rawContactUri,ContactsContract.RawContacts.Data.CONTENT_DIRECTORY);
Cursor cursor = managedQuery( dataUri, INFO_3,null, null, null);

方式二:另一種是利用RawContacts_ID或者Contact_ID,通過Data.CONTENT_URI,具體方式類RawContacts的檢索。

Cursor cursor = managedQuery(ContactsContract.Data.CONTENT_URI ,
                                                     INFO_3 ,
                                          ContactsContract.Data.RAW_CONTACT_ID + "=?" ,
                                          new String[]{String.valueOf(rawId)} ,
                                                    null);

總結一下架構圖。實際上Android的連絡人提供了多種URI的的查詢方式,具體參加Android的reference。

相關連結:我的Andriod開發相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.