android contacts data

content provider

Demo是給的一個聯繫人的栗子:點擊打開鏈接

part1

contacts:

 A CursorLoader runs its query on a thread that's separate from the UI thread. 

首先需要權限:READ_CONTACTS

ContactsContract don't have to define your own constants for content URIs, table names, or columns

uses a CursorLoader to retrieve data from the provider, you must specify that it implements the loader interface LoaderManager.LoaderCallbacks.

 Contacts.DISPLAY_NAME_PRIMARY requires Android 3.0 ,in versions previous to that, its name is Contacts.DISPLAY_NAME.

 Contacts._ID and LOOKUP_KEY are used together to construct a content URI for the contact the user selects.

Using "?" as a placeholder ensures that the search specification is generated by binding rather than by SQL compilation. so eliminates the possibility of malicious SQL injection. 


use a CursorLoader to retrieve data from the Contacts Provider. 主要是實現LoaderCallbacks接口

using a CursorLoader to retrieve data, you must initialize the background thread and other variables that control asynchronous retrieval.開的是異步線程。


public class ContactsFragment extends Fragment implements

        LoaderManager.LoaderCallbacks<Cursor> {

    ...

    // Called just before the Fragment displays its UI

    @Override

    public void onActivityCreated(Bundle savedInstanceState) {

        // Always call the super method first

        super.onActivityCreated(savedInstanceState);

        ...

        // Initializes the loader

        getLoaderManager().initLoader(0, null, this);

    }

同時實現接口函數onCreateLoader(), which is called by the loader framework immediately after you call initLoader().In onCreateLoader(), set up the search string pattern. 主要是返回一個CursorLoader。爲了將字符串改爲pattern,插入%表示0或多個字符,_表示一個字符,To make a string into a pattern, insert "%" (percent) characters to represent a sequence of zero or more characters, or "_" (underscore) characters to represent a single character, or both. For example, the pattern "%Jefferson%" would match both "Thomas Jefferson" and "Jefferson Davis".

@Override

    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {

        /*

         * Makes search string into pattern and

         * stores it in the selection array

         */

        mSelectionArgs[0] = "%" + mSearchString + "%";

        // Starts the query

        return new CursorLoader(

                getActivity(),

                Contacts.CONTENT_URI,

                PROJECTION,

                SELECTION,

                mSelectionArgs,

                null

        );

    }

實現onLoadFinished,將Cursor的結果顯示在list view上,調用swapCursor

The loader framework calls onLoadFinished() when the Contacts Provider returns the results of the query. In this method, put the result Cursor in the SimpleCursorAdapter. This automatically updates the ListView with the search results:

    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {

        // Put the result Cursor in the adapter for the ListView

        mCursorAdapter.swapCursor(cursor);

    }

實現接口中的onLoaderReset方法,如果接收到stale數據,則刪除adapter指向當前cursor的引用,否則會內存泄露。

The method onLoaderReset() is invoked when the loader framework detects that the result Cursor contains stale data. Delete the SimpleCursorAdapter reference to the existing Cursor. If you don't, the loader framework will not recycle the Cursor, which causes a memory leak. For example:

    @Override

    public void onLoaderReset(Loader<Cursor> loader) {

        // Delete the reference to the existing Cursor

        mCursorAdapter.swapCursor(null);這裏的adapter是CursorAdapter類型的變量

    }

}



part2

顯示contacts數據時,使用一個fragment,首先Initialize the Fragment. Add the empty, public constructor required by the Android system, and inflate the Fragment object's UI in the callback method onCreateView().


// Empty public constructor, required by the system

    public ContactsFragment() {}


    // A UI Fragment must inflate its View

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

            Bundle savedInstanceState) {

        // Inflate the fragment layout

        return inflater.inflate(R.layout.contact_list_fragment, container, false);

    }


點擊事件,獲取activity中的cursor,並且移動顯示

@Override

    public void onItemClick(

        AdapterView<?> parent, View item, int position, long rowID) {

        // Get the Cursor

        Cursor cursor = parent.getAdapter().getCursor();

        // Move to the selected contact

        cursor.moveToPosition(position);

        // Get the _ID value

        mContactId = getLong(CONTACT_ID_INDEX);

        // Get the selected LOOKUP KEY

        mContactKey = getString(CONTACT_KEY_INDEX);

        // Create the contact's content Uri

        mContactUri = Contacts.getLookupUri(mContactId, mContactKey);

        /*

         * You can use mContactUri as the content URI for retrieving

         * the details for a contact.

         */

    }


在activity裏,創建時

public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);

        ...

        // Gets the ListView from the View list of the parent activity

        mContactsList =

            (ListView) getActivity().findViewById(R.layout.contact_list_view);

        // Gets a CursorAdapter

        mCursorAdapter = new SimpleCursorAdapter(

                getActivity(),

                R.layout.contact_list_item,

                null,

                FROM_COLUMNS, TO_IDS,

                0);

        // Sets the adapter for the ListView

        mContactsList.setAdapter(mCursorAdapter);

    }


總結

To implement this type of retrieval, first implement the following code, as listed in previous sections:

  • Request Permission to Read the Provider.
  • Define ListView and item layouts.
  • Define a Fragment that displays the list of contacts.
  • Define global variables.
  • Initialize the Fragment.
  • Set up the CursorAdapter for the ListView.
  • Set the selected contact listener.
  • Define constants for the Cursor column indexes.Although you're retrieving data from a different table, the order of the columns in the projection is the same, so you can use the same indexes for the Cursor.
  • Define the onItemClick() method.
  • Initialize the loader.
  • Implement onLoadFinished() and onLoaderReset().
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章