【Android Developers Training】 99. 擷取連絡人詳細資料

來源:互聯網
上載者:User

標籤:android   des   style   blog   class   code   java   tar   javascript   ext   strong   

註:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由於喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。

原文連結:http://developer.android.com/training/contacts-provider/retrieve-details.html

這節課將會展示如何擷取一個連絡人的詳細資料,比如電子郵件地址,電話號碼,等等。當使用者獲得一個連絡人後,他會想要查看他的詳細資料。你可以展示給他們所有的資訊,或者只展示某一特定類型的資訊,比如電子郵件地址。

這節課中,我們假設你已經有了使用者選擇的一行ContactsContract.Contacts連絡人資料。在上一節課中(部落格連結:http://www.cnblogs.com/jdneo/p/3674830.html)我們已經講解了如何擷取連絡人清單的知識。

一). 擷取一個連絡人的詳細資料

要獲得一個連絡人的所有資訊,需要搜尋ContactsContract.Data表的每一行,看是否包含有連絡人的LOOKUP_KEY。這一列可在ContactsContract.Data中獲得,因為Contacts Provider在ContactsContract.Contacts表和ContactsContract.Data表之間執行了一個隱式的串連。列LOOKUP_KEY的詳細資料在上一節課中(部落格連結:http://www.cnblogs.com/jdneo/p/3674830.html)已經講授過了。

Note:

擷取某一個連絡人的所有資訊會降低裝置的效能,因為它需要擷取ContactsContract.Data表中所有列的資料。在你使用這一方法前要考慮到它對效能的影響。

請求許可權

要從Contacts Provider中讀取資料,你的應用必須具有READ_CONTACTS許可權。要請求這一許可權,在資訊清單檔的<manifest>標籤中添加如下子標籤:

<uses-permission android:name="android.permission.READ_CONTACTS" />
配置一個投影

根據每一行所包含的的資料類型,它可能使用一些列或很多列。另外,資料類型的不同會導致資料再不同的列中。要保證你能獲得對於所有可能資料類型所對應的所有可能的列,你需要添加所有的列名到你的投影中。同時,如果要把結果Cursor和一個ListView綁定起來,要擷取Data._ID;否則,綁定不會產生效果。同時要擷取Data.MIMETYPE這樣你就可以標示出你獲得的每一行資料的類型,例如:

    private static final String PROJECTION =            {                Data._ID,                Data.MIMETYPE,                Data.DATA1,                Data.DATA2,                Data.DATA3,                Data.DATA4,                Data.DATA5,                Data.DATA6,                Data.DATA7,                Data.DATA8,                Data.DATA9,                Data.DATA10,                Data.DATA11,                Data.DATA12,                Data.DATA13,                Data.DATA14,                Data.DATA15            };

這一投影會為ContactsContract.Data表的一行擷取所有的列,使用在ContactsContract.Data類中所定義的列名。

或者,你也可以是用在ContactsContract.Data類中定義或者從它繼承的其它列常量。注意,列SYNC1到列SYNC4是被同步適配器使用的,所以他們的資料對我們現在的應用情境而言沒有用。

定義選擇標準

為你的選擇語句定義一個常量,它是一個儲存選擇語句的數組,以及一個儲存對應值的變數。使用Contacts.LOOKUP_KEY列來尋找連絡人,例如:

    // Defines the selection clause    private static final String SELECTION = Data.LOOKUP_KEY + " = ?";    // Defines the array to hold the search criteria    private String[] mSelectionArgs = { "" };    /*     * Defines a variable to contain the selection value. Once you     * have the Cursor from the Contacts table, and you‘ve selected     * the desired row, move the row‘s LOOKUP_KEY value into this     * variable.     */    private String mLookupKey;

在你的選擇語句中使用“?”作為預留位置,能保證搜尋語句是由綁定產生的而不是編譯產生的。這可以防止惡意的SQL注入攻擊。

定義排列順序

為結果Cursor定義你期望的排列順序。要讓某一類型資料的所有行根據Data.MIMETYPE來排列。這一語句會讓所有email的行放在一起,所有電話號碼的行放在一起,等等。例如:

    /*     * Defines a string that specifies a sort order of MIME type     */    private static final String SORT_ORDER = Data.MIMETYPE;

Note:

一些資料類型不使用子類,所以你不能用子類型來排序。相反的,你需要再返回的Cursor中進行迭代,確定當前行的資料類型,然後將使用子類型的行的資料儲存起來。當你完成讀cursor後,之後你就可以通過子類型排序並顯示結果。

初始化載入器

通常,我們在後台線程從Contacts Provider(以及其它所有的內容提供器)擷取資料。使用由LoaderManager類,以及LoaderManager.LoaderCallbacks介面所定義的載入器架構來執行背景擷取操作。

當你準備好擷取行後,通過調用)">initLoader()初始化載入器架構。將一個整形標識傳遞給該方法;這一標誌會傳遞給LoaderManager.LoaderCallbacks方法。它可以協助你區分這些載入器,從而在一個應用中使用多個載入器。

下面的代碼範例展示了如何初始化這個載入器架構:

public class DetailsFragment extends Fragment implements        LoaderManager.LoaderCallbacks<Cursor> {    ...    // Defines a constant that identifies the loader    DETAILS_QUERY_ID = 0;    ...    /*     * Invoked when the parent Activity is instantiated     * and the Fragment‘s UI is ready. Put final initialization     * steps here.     */    @Override    onActivityCreated(Bundle savedInstanceState) {        ...        // Initializes the loader framework        getLoaderManager().initLoader(DETAILS_QUERY_ID, null, this);

實現onCreateLoader()

實現onCreateLoader()方法,它會在你調用了)">initLoader()後被載入器架構調用。該方法返回一個CursorLoader。因為你在搜尋ContactsContract.Data表,所以使用Data.CONTENT_URI常量作為內容URI。例如:

    @Override    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {        // Choose the proper action        switch (loaderId) {            case DETAILS_QUERY_ID:            // Assigns the selection parameter            mSelectionArgs[0] = mLookupKey;            // Starts the query            CursorLoader mLoader =                    new CursorLoader(                            getActivity(),                            Data.CONTENT_URI,                            PROJECTION,                            SELECTION,                            mSelectionArgs,                            SORT_ORDER                    );            ...    }

實現onLoadFinished()和onLoaderReset()

實現, D)">onLoadFinished()方法。當Contacts Provider將查詢結果返回後,載入器架構會調用, D)">onLoadFinished()。例如:

    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {        switch (loader.getId()) {            case DETAILS_QUERY_ID:                    /*                     * Process the resulting Cursor here.                     */                }                break;            ...        }    }

當載入器檢測到結果中的資料發生了變化,那麼)">onLoaderReset()方法會被調用,此時,將所有存在的Cursor引用設定成null來移除它們。如果你不這麼做,載入器架構不會銷毀老的Cursor,這樣會導致記憶體泄露,例如:

    @Override    public void onLoaderReset(Loader<Cursor> loader) {        switch (loader.getId()) {            case DETAILS_QUERY_ID:                /*                 * If you have current references to the Cursor,                 * remove them here.                 */                }                break;    }
二). 擷取一個連絡人的特定資料

要擷取一個連絡人的特定資料,比如email,和檢索所有的詳細資料類似,你需要做的改變僅僅是實現課程Retrieve All Details for a Contact(部落格連結:http://www.cnblogs.com/jdneo/p/3674830.html)中列出的代碼:

投影

修改你的投影,使得列對應於特定的要搜尋的資料類型。同時修改投影,使用在ContactsContract.CommonDataKinds子類中對應於資料類型的列常量名。

選擇

修改選擇語句,搜尋對應於你的資料類型的MIMETYPE值。

排列順序

因為你值使用單一的詳細資料類型,所以不需要根據Data.MIMETYPE將返回的Cursor分類。

這些修改在下列章節中描述。

定義一個投影

定義你要擷取的列,使用ContactsContract.CommonDataKinds子類中對應於資料類型的列常量名。如果你想要將Cursor綁定到一個ListView上,要確保擷取“_ID”列。例如,要擷取email資料,定義下列投影:

    private static final String[] PROJECTION =            {                Email._ID,                Email.ADDRESS,                Email.TYPE,                Email.LABEL            };

注意這一投影使用ContactsContract.CommonDataKinds.Email類中定義的列名,而不是在類ContactsContract.Data中定義的列名。使用email的特定列名可以增加代碼的可讀性。

在投影中,你也可以使用在ContactsContract.CommonDataKinds子類中定義的其它列。

定義選擇標準

定義一個搜尋運算式,它擷取你想要的特定連絡人的LOOKUP_KEY和Data.MIMETYPE行資料。對於MIMETYPE的值對應的常量,用單引號(‘)將它括起來;否則,提供器會把常量認為是一個變數名而不是一個字串值。你不需要為它使用一個預留位置,因為你使用的是一個常量而不是一個使用者提供的值。例如:

    /*     * Defines the selection clause. Search for a lookup key     * and the Email MIME type     */    private static final String SELECTION =            Data.LOOKUP_KEY + " = ?" +            " AND " +            Data.MIMETYPE + " = " +            "‘" + Email.CONTENT_ITEM_TYPE + "‘";    // Defines the array to hold the search criteria    private String[] mSelectionArgs = { "" };

定義排列順序

為返回的Cursor定義一個排列順序。因為你獲得的是一個特定的資料類型,所以略過對MIMETYPE排序。另外,如果你正在搜尋的詳細資料包含有一個子類型,可以對他排序。例如,對於Email資料你可以根據Email.TYPE來排序:

    private static final String SORT_ORDER = Email.TYPE + " ASC ";
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.