The Contacts Provider is the central repository of the user's contacts information, including data from contacts apps and social networking apps. In your apps, you can access Contacts Provider information directly by calling
ContentResolver
methods or by sending intents to a contacts app.This class focuses on retrieving lists of contacts, displaying the details for a particular contact, and modifying contacts using intents. The basic techniques described here can be extended to perform more complex tasks. In addition, this class helps you understand the overall structure and operation of the Contacts Provider.
Lessons
- Retrieving a List of Contacts
- Learn how to retrieve a list of contacts for which the data matches all or part of a search string, using the following techniques:
- Match by contact name
- Match any type of contact data
- Match a specific type of contact data, such as a phone number
- Retrieving Details for a Contact
- Learn how to retrieve the details for a single contact. A contact's details are data such as phone numbers and email addresses. You can retrieve all details, or you can retrieve details of a specific type, such as all email addresses.
- Modifying Contacts Using Intents
- Learn how to modify a contact by sending an intent to the People app.
- Displaying the Quick Contact Badge
- Learn how to display the
QuickContactBadge
widget. When the user clicks the contact badge widget, a dialog opens that displays the contact's details and action buttons for apps that can handle the details. For example, if the contact has an email address, the dialog displays an action button for the default email app.
Retrieving a List of Contacts
This lesson shows you how to retrieve a list of contacts whose data matches all or part of a search string, using the following techniques:
- Match contact names
- Retrieve a list of contacts by matching the search string to all or part of the contact name data. The Contacts Provider allows multiple instances of the same name, so this technique can return a list of matches.
- Match a specific type of data, such as a phone number
- Retrieve a list of contacts by matching the search string to a particular type of detail data such as an email address. For example, this technique allows you to list all of the contacts whose email address matches the search string.
- Match any type of data
- Retrieve a list of contacts by matching the search string to any type of detail data, including name, phone number, street address, email address, and so forth. For example, this technique allows you to accept any type of data for a search string and then list the contacts for which the data matches the string.
Note: All the examples in this lesson use a
CursorLoader
to retrieve data from the Contacts Provider. A CursorLoader
runs its query on a thread that's separate from the UI thread. This ensures that the query doesn't slow down UI response times and cause a poor user experience. For more information, see the Android training class Loading Data in the Background.Request Permission to Read the Provider
To do any type of search of the Contacts Provider, your app must have
READ_CONTACTS
permission. To request this, add this <uses-permission>
element to your manifest file as a child element of <manifest>
:<uses-permission android:name="android.permission.READ_CONTACTS" />
Match a Contact by Name and List the Results
This technique tries to match a search string to the name of a contact or contacts in the Contact Provider's
ContactsContract.Contacts
table. You usually want to display the results in a ListView
, to allow the user to choose among the matched contacts.Define ListView and item layouts
To display the search results in a
ListView
, you need a main layout file that defines the entire UI including the ListView
, and an item layout file that defines one line of the ListView
. For example, you could create the main layout file res/layout/contacts_list_view.xml
with the following XML:<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
This XML uses the built-in Android
ListView
widget android:id/list
.
Define the item layout file
contacts_list_item.xml
with the following XML:<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true"/>
Define a Fragment that displays the list of contacts
To display the list of contacts, start by defining a
Fragment
that's loaded by an Activity
. Using a Fragment
is a more flexible technique, because you can use one Fragment
to display the list and a second Fragment
to display the details for a contact that the user chooses from the list. Using this approach, you can combine one of the techniques presented in this lesson with one from the lesson Retrieving Details for a Contact.
To learn how to use one or more
Fragment
objects from an an Activity
, read the training class Building a Dynamic UI with Fragments.
To help you write queries against the Contacts Provider, the Android framework provides a contracts class called
ContactsContract
, which defines useful constants and methods for accessing the provider. When you use this class, you don't have to define your own constants for content URIs, table names, or columns. To use this class, include the following statement:import android.provider.ContactsContract;
Since the code uses a
CursorLoader
to retrieve data from the provider, you must specify that it implements the loader interfaceLoaderManager.LoaderCallbacks
. Also, to help detect which contact the user selects from the list of search results, implement the adapter interfaceAdapterView.OnItemClickListener
. For example:... import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.widget.AdapterView; ... public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener {
Define global variables
Define global variables that are used in other parts of the code:
... /* * Defines an array that contains column names to move from * the Cursor to the ListView. */ @SuppressLint("InlinedApi") private final static String[] FROM_COLUMNS = { Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? Contacts.DISPLAY_NAME_PRIMARY : Contacts.DISPLAY_NAME }; /* * Defines an array that contains resource ids for the layout views * that get the Cursor column contents. The id is pre-defined in * the Android framework, so it is prefaced with "android.R.id" */ private final static int[] TO_IDS = { android.R.id.text1 }; // Define global mutable variables // Define a ListView object ListView mContactsList; // Define variables for the contact the user selects // The contact's _ID value long mContactId; // The contact's LOOKUP_KEY String mContactKey; // A content URI for the selected contact Uri mContactUri; // An adapter that binds the result Cursor to the ListView private SimpleCursorAdapter mCursorAdapter; ...
Note: Since
Contacts.DISPLAY_NAME_PRIMARY
requires Android 3.0 (API version 11) or later, setting your app's minSdkVersion
to 10 or below generates an Android Lint warning in Android Studio. To turn off this warning, add the annotation @SuppressLint("InlinedApi")
before the definition of FROM_COLUMNS
.Initialize the Fragment
Initialize the
Fragment
. Add the empty, public constructor required by the Android system, and inflate the Fragment
object's UI in the callback methodonCreateView()
. For example:// 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); }
Set up the CursorAdapter for the ListView
Set up the
SimpleCursorAdapter
that binds the results of the search to the ListView
. To get the ListView
object that displays the contacts, you need to call Activity.findViewById()
using the parent activity of the Fragment
. Use the Context
of the parent activity when you call setAdapter()
. For example: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); }
Set the selected contact listener
Define the onItemClick() method
In a previous section, you set the item click listener for the
ListView
. Now implement the action for the listener by defining the methodAdapterView.OnItemClickListener.onItemClick()
:@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. */ }
沒有留言:
張貼留言