Note: This article is translated from Google's official Android developers training document, translator technology generally, because of the love of Android and produced the idea of translation, purely personal interests and interests.
Original link: http://developer.android.com/training/contacts-provider/retrieve-details.html
This lesson will show you how to get detailed data for a contact, such as an email address, phone number, and so on. When a user obtains a contact, he will want to see his details. You can show them all the information, or just display a specific type of information, such as an email address.
In this lesson, we assume that you already have a user-selected line of contactscontract.contacts contact data. In the previous lesson (blog link: http://www.cnblogs.com/jdneo/p/3674830.html) We have already explained how to get the contact list knowledge.
a). Get more information about a contact
To get all the information for a contact, you need to search each row of the Contactscontract.data table to see if there is a lookup_key with the contact person. This column can be obtained in Contactscontract.data because the contacts provider performs an implicit connection between the Contactscontract.contacts table and the Contactscontract.data table. Detailed information about column Lookup_key has been taught in the previous lesson (blog link:http://www.cnblogs.com/jdneo/p/3674830.html) .
Note:
Getting all the information for a contact degrades the performance of the device because it needs to get data for all the columns in the Contactscontract.data table. Before you use this method, take into account its impact on performance.
Request Permission
To read data from contacts provider, your app must have read_contacts permissions. To request this permission, add the following sub-label to the <manifest> tag in the manifest file:
<android:name= "Android.permission.READ_CONTACTS"/>
Configure a projection
Depending on the type of data contained in each row, it may use some columns or many columns. In addition, different data types cause data to be in different columns. To ensure that you have all possible columns for all possible data types, you need to add all the column names to your projection. At the same time, if you want to bind the result cursor to a ListView, get data._id; otherwise, the binding will not have an effect. Also get data.mimetype so that you can indicate the type of data you have obtained for each row, for example:
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 };
This projection gets all the columns for a row of the Contactscontract.data table, using the column names defined in the Contactscontract.data class.
Alternatively, you can use other column constants that are defined in the Contactscontract.data class or inherited from it. Note that the column SYNC1 to column SYNC4 is used by the sync adapter, so their data is useless for our current application scenario.
Define selection Criteria
Define a constant for your selection statement, which is an array of saved selection statements, and a variable that holds the corresponding values. Use the Contacts.lookup_key column to find contacts, for example:
//defines the selection clause Private Static FinalString SELECTION = Data.lookup_key + "=?"; //Defines the array to hold the search criteria PrivateString[] Mselectionargs = {"" }; /** Defines a variable to contain the selection value. Once you * has the Cursor from the Contacts table, and you ' ve selected * The desired row, move the row ' s Lookup_k EY value into this * variable. */ PrivateString Mlookupkey;
Use "?" in your selection statement As placeholders, the search statements are guaranteed to be generated by the bindings rather than compiled. This can prevent malicious SQL injection attacks.
Defining the sorting order
Define the sort order you want for the result cursor. To have all rows of a type of data arranged according to Data.mimetype. This statement puts all the lines of the email together, the lines of all the phone numbers together, and so on. For example:
/* * Defines a string that specifies a sort order of MIME type */ privateSTA Ticfinal String sort_order = Data.mimetype;
Note:
Some data types do not use subclasses, so you cannot sort by subtypes. Instead, you need to iterate through the cursor again, determine the data type of the current row, and then save the data for the rows that use the subtype. Once you have finished reading the cursor, you can then sort and display the results by subtype.
Initializing the loader
Typically, we get data from contacts Provider (and all other content providers) in a background thread. Use the loader framework defined by the Loadermanager class, as well as the Loadermanager.loadercallbacks interface, to perform a background fetch operation.
When you are ready to get the row, call the >initloader () to initialize the loader framework. Pass a shaping identity to the method; This flag is passed to the Loadermanager.loadercallbacks method. It can help you differentiate between these loaders, thus using multiple loaders in one application.
The following code sample shows how to initialize the loader framework:
Public classDetailsfragmentextendsFragmentImplementsLoadermanager.loadercallbacks<Cursor> { ... //defines a constant that identifies the loaderdetails_query_id = 0; ... /** Invoked when the parent Activity was instantiated * and the Fragment ' s UI is ready. Put Final Initialization * steps here. */@Override onactivitycreated (Bundle savedinstancestate) {...//initializes the loader frameworkGetloadermanager (). Initloader (details_query_id,NULL, This);
implement Oncreateloader ()
Implement the Oncreateloader () method, which will be called by the loader framework after you call the >initloader (). The method returns a Cursorloader. Because you are searching the Contactscontract.data table, use the Data.content_uri constant as the content URI. For example:
@Override PublicLoader<cursor> Oncreateloader (intLoaderid, Bundle args) { //Choose the proper action Switch(Loaderid) { Casedetails_query_id://assigns the selection parameterMselectionargs[0] =Mlookupkey; //starts the queryCursorloader Mloader =NewCursorloader (Getactivity (), Data.content_uri, PROJECTION, SELECTION, Mselectionargs, Sort_order); ... }
Implement Onloadfinished () and Onloaderreset ()
Implementation, D) ">onloadfinished () method. When contacts provider returns the query results, the loader framework calls, D) ">onloadfinished (). For example:
Public void onloadfinished (loader<cursor> Loader, cursor cursor) { switch ( Loader.getid ()) { case details_query_id: / * * Process the Resulting Cursor here. */ } break; ... } }
When the loader detects that the data in the result has changed, the >onloaderreset () method is called, at which point all existing cursor references are set to NULL to remove them. If you do not do this, the loader framework does not destroy the old cursor, which can lead to memory leaks, such as:
@Override publicvoid onloaderreset (loader<cursor> Loader) { Switch (Loader.getid ()) { case details_query_id: /* * If you had current references to the Cursor, * Remove them here. */ } break;
b). Get specific data for a contact
To get a contact's specific data, such as email, and to retrieve all the details like that, you need to do a change just to implement the course retrieve all details for a contacts(blog link:/http// www.cnblogs.com/jdneo/p/3674830.html) The code listed in:
Projection
Modify your projection so that the column corresponds to a specific type of data to be searched. Modify the projection at the same time, using the column constant name that corresponds to the data type in the Contactscontract.commondatakinds subclass.
Choose
Modify the selection statement to search for the MimeType value that corresponds to your data type.
Sort order
Because you value using a single detail data type, you do not need to classify the cursor that is returned according to Data.mimetype.
These changes are described in the following sections.
Define a projection
Define the column you want to get, using the name of the column constant that corresponds to the data type in the Contactscontract.commondatakinds subclass. If you want to bind the cursor to a ListView, be sure to get the "_id" column. For example, to get the email data, define the following projections:
Private Static Final string[] PROJECTION = { email._id, email.address, email.type, Email.label };
Note that this projection uses the column names defined in the ContactsContract.CommonDataKinds.Email class instead of the column names defined in the class Contactscontract.data. Using specific column names for email can increase the readability of your code.
In the projection, you can also use other columns that are defined in the Contactscontract.commondatakinds subclass.
Define selection Criteria
Define a search expression that gets the Lookup_key and data.mimetype rows of data for the specific contact you want. For a constant of the value of mimetype, enclose it in single quotation marks ('); otherwise, the provider will think of the constant as a variable name instead of a string value. You do not need to use a placeholder for it because you are using a constant instead of a user-supplied value. For example:
/* * Defines the selection clause. Search for a lookup key * and the Email MIME type */ privatestatic Final String SELECTION = + "=?" + "+" + + "=" + "'" + Email.conten T_item_type + "'"; // Defines the array to hold the search criteria Private String[] Mselectionargs = {""};
Defining the sorting order
Defines a sort order for the returned cursor. Because what you get is a specific data type, so skip to sort mimetype. Also, if you are searching for detailed data that contains a subtype, you can sort on him. For example, for email data you can sort by Email.type:
Private Static Final String Sort_order = email.type + "ASC";