Android study note 21. Use ContentProvider for data sharing (4). ContentProvider and androidprovider of the Operating System (contact)

Source: Internet
Author: User

Android study note 21. Use ContentProvider for data sharing (4). ContentProvider and androidprovider of the Operating System (contact)
The Android system provides a large number of contentproviders, such as contact information and multimedia information of the system. Our developed applications mainly call the query () provided by the system's ContentProvider through ContentResolver (), insert (), update (), and delete () methods to obtain data in Android.1. How to Use the internal data exposed by ContentResolver operating system ContentProvider?1. Call getContentResolver () of the Activity to obtain the ContentResolver object; 2. Call the insert (), delete (), update (), and query () Methods of ContentResolver to operate data as needed.Ii. Source Code Analysis1. Add read/write permissions<Uses-permission android: name = "android. permission. READ_CONTACTS "//> // grant the read contact ContentProvider permission <uses-permission android: name =" android. permission. WRITE_CONTACTS "//> // grant the write contact ContentProvider permission2. The Uri of the contact ContentProvider(1) ContactsContract. contacts. CONTENT_URI (content: // com. android. contacts/contacts): Manage the contact's Uri; (2) ContactsContract. commonDataKinds. phone. CONTENT_URI (content: // com. android. contacts/data/phones): Uri used to manage the contact's phone number; (3) ContactsContract. commonDataKinds. email. CONTENT_URI (content: // com. android. contacts/data/emails): used to manage the e-mail Uri of a contact.3.Obtain the Cursor object of the table of all contacts:
1) ContentResolver contentResolver = getContentResolver (); // obtain the shared object defined in ContentResolver object query; 2) Cursor cursor = contentResolver. query (ContactsContract. contacts. CONTENT_URI, null, null); // according to the URI object ContactsContract. contacts. CONTENT_URI query all contacts4. Obtain the specific information of the specified contact (_ ID ).From the Cursor object, the key is to obtain the contact's _ id. It then queries the Phone number (ContactsContract. CommonDataKinds. CommonDataKinds. Phone) and email (ContactsContract. CommonDataKinds. Email) of the _ id contact through the Child classes of ContactsContract. Take all calls from this contact as an example: 1) int idFieldIndex = cursor. getColumnIndex (ContactsContract. contacts. _ ID); int id = cursor. getInt (idFieldIndex); // obtain the contact id based on the column name; 2) Cursor phonecursor = contentResolver. query (ContactsContract. commonDataKinds. phone. CONTENT_URI, null, ContactsContract. commonDataKinds. phone. CONTACT_ID + "=" + id, null, null); // class ContactsContract. commonDataKinds. query all the Phone numbers of contacts with the corresponding id. Similarly, ContactsContract can be used. commonDat Different sub-classes of aKinds query different contents. The android document tells us that we recommend using ContactsContract. Contacts. LOOKUP_KEY instead of ContactsContract. Contacts. _ ID.

Sublimation Note: 1. Cursor interface (1) function Overview: this interface is mainly used to randomly read and write the results in the form of a set returned by the query from the database. (2) Common method: abstract void close (): close Cursor and release all resources abstract boolean moveToNext (): move the Cursor to the next line String getString (int columnIndex ): convert the value of the specified column index to a String and return int getColumnIndex (String columnName): returns the index value of the specified column name (an integer value starting with 0 ), the input parameter is the column name. 2. because the resources occupied by reading contacts are compared, in order to improve the user experience. We recommend that you use the AsyncTask class. When reading the address book of the Android system, the contacts are generally read first and then their numbers are read in a nested loop. If the number of contacts in the address book is small, the speed is acceptable, but the number of people in the address book is 1 to 2, I am afraid it will be slow. If the hardware is almost worse, the experience will be worse. You can use the ContactsContract. CommonDataKinds. Phone. CONTENT_URI (corresponding to the contacts2.db data view view_data_restricted) view to read and avoid nested reading. For PhoneLookup. CONTENT_FILTER_URI 4. Contact's API(1) ContactsContract [public final class] java. lang. object upload android. provider. contactsContract is a contract between the contact data Provider and the application. It defines all supported Content Provider Uris and data columns. Since Android 2.0 (API Level 5), the Android platform provides an improved Contacts API to meet the needs of a contact who can have multiple accounts, such as mobile phone address book and GMAIL address book, the two records in the two address books can be the same person. The new Contacts API is mainly managed by ContactsContract and its related classes. The old API (android. provider. contacts) is not supported, but can still be used for compatibility, but as before, only the information of the first account can be returned. In the new Contacts API, contact Data is put into three tables: Contacts, RawContacts, and Data. This helps the system better store and manage the information of multiple accounts of a contact. ContactsContract table structure:. contactsContract. data is used to save personal Data, such as phone numbers, emails, ringtones, instant messaging methods, and photos. contactsContract. rawContacts is used to associate contact information with accounts. Because mobile phone contact information may be imported from different Gmail or other places, the account concept is introduced for Mutual Difference and convenience of synchronization. C. contactsContract. contacts belongs to a contact under different accounts and may describe the same person. This table is the union of RawContacts. If a contact information is modified, the information of the same person as the description must be updated accordingly.
(2) The ContactsContract. Data Table stores the contact details. Each row in the table stores a specific type of information, such as Email, Address, or Phone. Each row uses a mimetype_id field to indicate the type of data stored in the row. This field references the mimetyps table, which stores common data types. The fields in the Data table mainly include: mimetype_id: the type of information stored in the row raw_contact_id: The RawContactis_primary to which the row belongs: multiple data Data to form a raw contact, this field indicates whether the data is the raw contact's master data, that is, its display name will be used as the display nameis_super_primary of raw contact: whether the data is the master data of the contact to which it belongs, if is_super_primary is 1, is_primary must be 1data1 ~ Data15: 15 data fields. Different types of information indicate different meanings. ContactsContract. the CommomDataKinds class defines classes that correspond to common data types. These Classes define the meanings of these fields in the corresponding data types. Generally, the data1 table is the primary information (such as the phone number and Email address). data2 indicates the secondary information, and data15 indicates the Blob data. Data_sync1 ~ Data_sync4 sync_adapter: used field (sync_adapter is used for data synchronization, such as the synchronization between your Gmail account and Google server on your mobile phone ). Data_version: The data version used for data synchronization. Data in the Data class. CONTACT_ID and Data. RAW_CONTACT_ID indicates the ID of the Contact corresponding to the table item in the Contact and RawContract tables. We only need to know the contactId or rawContractId of a Contact, you can find the corresponding type of information based on the data type you are searching. (3) ContactsContract. a row in the RawContact table stores a set of Data rows and other information in the Data table, indicating the information of a specific account of a contact, such as a contact of Facebook or Exchange. When a raw contact is inserted or the data of a raw contact changes, the system checks whether the raw contact matches other raw contacts (for example, if the data of two raw contacts contains the same phone number or name ), if they match, they will be combined, that is, they will belong to the same cantact, as they reference the same cantact_id in the RawContact table. A change in the contact name, organization, phone number, Email, or nickname will trigger a re-aggregation of raw contact. There are two methods to control aggregate behavior Aggregaton Mode and ContactsContract. AggregationExceptions. Aggregaton Mode: there is a field aggregation_mode in the RawContact table. By inserting this field into a specific raw contact row, the system can modify the aggregation behavior of this raw contact. The permitted values are as follows: AGGREGATION_MODE_DEFAULT: in normal mode, automatic aggregation is allowed; AGGREGATION_MODE_DISABLE: aggregation is not allowed; aggregation_mode_suincluded: If a raw contact's aggregation mode is changed to suincluded, if it is already part of an aggregated contact, it will maintain the relationship with the original raw contact, even if it has changed and does not match other raw contact. ContactsContract. AggregationExceptions: A table named agg_exceptions exists in the database. Two raw contact aggregation methods are stored through the raw_contact_id1, raw_contact_id2, and mode fields. The system defines three aggregation behaviors: TYPE_AUTOMATIC = 0, which is determined by the system. The default value is 0. TYPE_KEEP_SEPARATE = 2 do not aggregate TYPE_KEEP_TOGETHER = 1 aggregate (4) ContactsContract. a row in the ContactContact table represents a contact. It is a combination of one or more rows in the RawContact table. The rows in the RawContact table indicate different account information of the same person. The data in the Contact table is automatically generated by the system combination RawContact table. Data cannot be directly inserted into this table. When a raw contact is inserted, the system first looks for the Contact table to see if there are records that indicate the same person as the inserted raw contact, if yes, insert the _ ID of the contact to the CONTACT_ID field of the raw contact record. If no value is found, the system automatically inserts a Contact record and inserts its _ ID into the CONTACT_ID column of the newly inserted raw contact. Only the TIMES_CONTACTED, LAST_TIME_CONTACTED, STARRED, CUSTOM_RINGTONE, and SENE_TO_VOICEMAIL columns in the Contact table can be changed. changes to these columns will cause the corresponding raw contact to be changed. When a record in the Contact table is deleted, the information of all accounts of a Contact is deleted, that is, all raw contacts corresponding to the Contact table are also deleted, the data corresponding to each raw contact is deleted, and the corresponding records on the server are also deleted during sync adapter synchronization. If you want to read the information of a contact, use CONTENT_LOOKUP_RUI instead of CONTENT_URI (see below). If you want to find a contact by phone number, use PhoneLookup. CONTENT_FIILTER_URI, Which is optimized for this purpose. If you need to search by matching some names, use CONTENT_FILTER_URI. If you need to search by email, address, or other information, find the table ContactsContract. data, the result contains the contact ID, name... contactsContract subclass ContactsContract. contacts is a table that represents the statistics of all Contacts. For example, contact ID (-ID), query key (LOOKUP_KEY), contact name (DISPLAY_NAME_PRIMARY), Avatar id (PHOTO_ID), and group id.
(5) ContactsContract. CommonDataKinds classIn the previous section on the structure of Data tables, we talked about data1 ~ The data15 field is used to store data information of various types. What information does the 15 fields represent? As mentioned above, there is a mimetype_id field in the Data table. Using this field to associate the mimetypes table indicates the information type represented by this row, because each row in the Data table can represent different types of information such as Phone or Address, for different types of information, data1 ~ The 15 columns of data15 indicate different meanings. If you need to remember the meaning of these 15 columns for specific types, it will not work, So Google predefines some classes, each class corresponds to some pre-defined data types, and each class defines some semantic and easy-to-remember constants to correspond to these 15 fields, such as in CommonDataKinds. the following definitions are available in the Email class: publicstaticfinal String ADDRESS = DATA1; publicstaticfinal String DISPLAY_NAME = DATA4; DATA1 and DATA4 are constants inherited from DataColumns, which are defined in DataColumns as follows: publicstaticfinal String DATA1 = "data1"; publicstaticfinal String DATA4 = "data4"; in this way, you only need to use Contacts to find the Email address. Contract. CommonDataKinds. Email. ADDRESS reference, without knowing that it is stored in the data1 column of the Data table. Iii. Source Code
Public class ContactProviderTest extends Activity {@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); Button search = (Button) findViewById (R. id. searchBtn);/* query contacts */search. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {// 1. define two lists to encapsulate the contact information of the system. Specify the contact's phone number, Email, and other details. final ArrayList <String> names = new ArrayList <String> (); final ArrayList <String> details = new ArrayList <String> (); // 2. use ContentResolver to Query the given URI, returning a Cursor over the result set) Cursor cursor = getContentResolver (). query (ContactsContract. contacts. CONTENT_URI, null, null); // 3. traverse the query results to obtain all contacts in the system while (cursor. moveToNext () {//. obtain the contact ID String contactId = cursor. getString (cursor. getColumnIndex (ContactsContract. contacts. _ ID); // B. obtain the contact name String name = cursor. getString (cursor. getColumnIndex (ContactsContract. contacts. DISPLAY_NAME); names. add (name); // add the name to the List in sequence/* dependencies * // c. use ContentResolver to find the contact's phone number Cursor phones = getContentResolver (). query (ContactsContract. commonDataKinds. phone. CONTENT_URI, null, ContactsContract. commonDataKinds. phone. CONTACT_ID + "=" + contactId, null, null); // d. traverse the query results to obtain the ArrayList of multiple phone numbers of the contact <String> detail = new ArrayList <String> (); while (phones. moveToNext () {String phoneNumber = phones. getString (phones. getColumnIndex (ContactsContract. commonDataKinds. phone. NUMBER); detail. add ("phone number" + phoneNumber);} phones. close ();/* else * // e. use ContentResolver to find the contact's e-mail address Cursor emails = getContentResolver (). query (ContactsContract. commonDataKinds. email. CONTENT_URI, null, ContactsContract. commonDataKinds. email. CONTACT_ID + "=" + contactId, null, null); // f. traverse the query results and obtain multiple email addresses of the contact while (emails. moveToNext () {String emailAddress = emails. getString (emails. getColumnIndex (ContactsContract. commonDataKinds. email. DATA); detail. add ("email address:" + emailAddress);} emails. close (); details. add (detail);} cursor. close ();/* success * // 4. load result. xml View resultDialog = getLayoutInflater (). inflate (R. layout. result, null); // 5. obtain the ExpandableListView (ExpandableListView) resultDialog in resultDialog. findViewById (R. id. list); // 6. create an ExpandableListAdapter object ExpandableListAdapter adapter = new BaseExpandableListAdapter () {//. obtain the sub-list item data at the specified group position and specified sub-list item @ Override public Object getChild (int groupPosition, int childPosition) {return details. get (groupPosition ). get (childPosition) ;}@ Override public long getChildId (int groupPosition, int childPosition) {return childPosition ;}@ Override public int getChildrenCount (int groupPosition) {return details. get (groupPosition ). size ();} private TextView getTextView () {AbsListView. layoutParams lp = new AbsListView. layoutParams (ViewGroup. layoutParams. MATCH_PARENT, 64); TextView textView = new TextView (ContactProviderTest. this); textView. setLayoutParams (lp); textView. setGravity (Gravity. CENTER_VERTICAL | Gravity. LEFT); textView. setPadding (36, 0, 0, 0); textView. setTextSize (20); return textView;} // B. this method determines the appearance of each sub-option @ Override public View getChildView (int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {TextView textView = getTextView (); textView. setText (getChild (groupPosition, childPosition ). toString (); return textView;} // c. obtain the group data at the specified group position @ Override public Object getGroup (int groupPosition) {return names. get (groupPosition) ;}@ Override public int getGroupCount () {return names. size () ;}@ Override public long getGroupId (int groupPosition) {return groupPosition;} // d. this method determines the appearance of each group option @ Override public View getGroupView (int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {TextView textView = getTextView (); textView. setText (getGroup (groupPosition ). toString (); return textView;} @ Override public boolean isChildSelectable (int groupPosition, int childPosition) {return true ;}@ Override public boolean hasStableIds () {return true ;}}; // 7. set the list of Adapter objects for ExpandableListView. setAdapter (adapter); // 8. use the dialog box to display the query result new AlertDialog. builder (ContactProviderTest. this ). setView (resultDialog ). setPositiveButton ("OK", null ). show () ;}});/* add contact */Button add = (Button) findViewById (R. id. addBtn); add. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {//. obtain the three textbox String name = (EditText) findViewById (R. id. name )). getText (). toString (); String phone = (EditText) findViewById (R. id. phone )). getText (). toString (); String email = (EditText) findViewById (R. id. email )). getText (). toString (); // B. create an empty ContentValues values = new ContentValues (); // c. to RawContacts. CONTENT_URI: Is a null value inserted to obtain rawContactId Uri rawContactUri = getContentResolver () returned by the system (). insert (RawContacts. CONTENT_URI, values); long rawContactId = ContentUris. parseId (rawContactUri); values. clear ();/* ----------------------------------------------------- */values. put (Data. RAW_CONTACT_ID, rawContactId); // d. set the content type values. put (Data. MIMETYPE, StructuredName. CONTENT_ITEM_TYPE); // e. set the contact name values. put (StructuredName. GIVEN_NAME, name); // f. add the contact name getContentResolver () to the contact URI (). insert (android. provider. contactsContract. data. CONTENT_URI, values); values. clear ();/* ----------------------------------------------------- */values. put (Data. RAW_CONTACT_ID, rawContactId); values. put (Data. MIMETYPE, Phone. CONTENT_ITEM_TYPE); // g. set the contact's phone number values. put (Phone. NUMBER, phone); // h. set the telephone type values. put (Phone. TYPE, Phone. TYPE_MOBILE); // I. add the phone number getContentResolver () to the contact phone number URI (). insert (android. provider. contactsContract. data. CONTENT_URI, values); values. clear ();/* ----------------------------------------------------- */values. put (Data. RAW_CONTACT_ID, rawContactId); values. put (Data. MIMETYPE, Email. CONTENT_ITEM_TYPE); // j. set the contact's e-mail address values. put (Email. DATA, email); // k. set the email type values. put (Email. TYPE, Email. TYPE_WORK); // l. add the email data getContentResolver () to the contact's email URI (). insert (android. provider. contactsContract. data. CONTENT_URI, values); Toast. makeText (ContactProviderTest. this, "the contact data is successfully added", Toast. LENGTH_SHORT ). show ();}});}}

The effect is as follows:
Reference: http://blog.163.com/hesky_fly/blog/static/732868692011102311551131/http://wear.techbrood.com/reference/android/provider/ContactsContract.Data.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.