We all know that ContentProvider is used to share data, but Android itself provides a lot of contentprovider, such as contact information, system multimedia information, etc. The contentprovider of these systems provide URIs for other applications to access, and developers can invoke the contentresolver of the system via the ContentProvider provided insert ()/update ()/delete () /query () method to achieve your own needs.
1, understand the structure of the system contact person
(1) The Android system provides a lot of URIs for contact management, with the most of the following:
ContactsContract.Contacts.CONTENT_URI: Manage the URI of the contact person
ContactsContract.CommonDataKinds.Phone.CONTENT_URI: Managing the URI of a contact phone
ContactsContract.CommonDataKinds.Email.CONTENT_URI: Managing the URI of a contact's mailbox
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI: The URI that manages the contact address
We can according to the system to provide these URIs to the operating system contact information, there are many specific content_uri, you can go to the Contactscontract.class file to see the source code.
(2) Table structure
As we said before, ContentProvider is the form of a table to store the data, the system contact is the case, generally stored in the data/data/com.android.providers.contacts/databases/ In Contacts2.db, we can look through the adb shell command line, or we can export this contacts2.db file through the SQLite tool, and here for our export.
Locate the file, and then click the Export button in the upper-right corner to export the file to a location in the system
To open the exported file with a tool, here's what I'm using: Navicat Premium
Tables and Views:
We often use to have: Contacts, data, raw_contacts three tables:
Contacts table:
_ID: The ID of the table, mainly used in other tables to find the appropriate data through the IDs in the Contacts table.
Display_name: Contact Name
PHOTO_ID: Avatar ID, if no contact avatar is set, this field is empty
times_contacted: Number of call records
Last_time_contacted: Last Call time
Lookup: is a persistent store because the user may change his name, but it will not alter lookup.
Data table:
RAW_CONTACT_ID: The relative data in the Raw_contact table can be found by raw_contact_id.
Data1 to data15 here to keep contact information contact name Contact Phone Number Email comments etc
Raw_contacts table:
Version: edition number, for monitoring changes
Deleted: Delete flag, 0 is default 1 means this row of data has been deleted
Display_name: Contact Name
Last_time_contacts: The Last contact time
"Description: Because these tables are very many fields, screenshots are not complete, you can try to export a look at"
2, Code implementation
(1) To first configure read and write access to system contacts in the Androidmanifest.xml file:
<!--add permission to manipulate contacts-->
<uses-permission android:name= "Android.permission.READ_CONTACTS"/>
<uses-permission android:name= "Android.permission.WRITE_CONTACTS"/>
(2) Layout file
The first is the list display page:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
android:orientation= "Vertical" >
<textview
Android:layout_width= "Fill_parent"
android:layout_height= "50DP"
Android:gravity= "Center_vertical"
Android:text= "My Contacts."
Android:textsize= "25DP"/>
<linearlayout
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content"
android:orientation= "Horizontal"
Android:background= "@android: Color/darker_gray" >
<textview
Android:id= "@+id/id"
Android:layout_width= "0DP"
android:layout_height= "30DP"
android:layout_weight= "1"
android:text= "ID"
android:gravity= "Center"/>
<textview
Android:id= "@+id/name"
Android:layout_width= "0DP"
android:layout_height= "30DP"
android:layout_weight= "1"
android:text= "Name"
android:gravity= "Center"/>
<textview
Android:id= "@+id/phone"
Android:layout_width= "0DP"
android:layout_height= "30DP"
android:layout_weight= "1"
android:text= "mobile phone number"
android:gravity= "Center"/>
</LinearLayout>
<listview
Android:id= "@+id/listview"
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content"
android:layout_gravity= "Center"
Android:divider= "#FF0000"
android:dividerheight= "1DP"
Android:focusable= "true"
android:minheight= "40DP"
Android:footerdividersenabled= "false" >
</ListView>
</LinearLayout>
The ListView page layout to use in the list presentation:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
android:orientation= "Horizontal" >
<textview
Android:id= "@+id/id"
Android:layout_width= "0DP"
android:layout_weight= "1"
android:gravity= "Center"
android:layout_height= "40DP"
/>
<textview
Android:id= "@+id/name"
Android:layout_width= "0DP"
android:layout_weight= "1"
android:gravity= "Center"
android:layout_height= "40DP"
/>
<textview
Android:id= "@+id/phone"
Android:layout_width= "0DP"
android:layout_weight= "1"
android:gravity= "Center"
android:layout_height= "40DP"
/>
</LinearLayout>
To add a contact interface:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
android:orientation= "Vertical" >
<linearlayout
Android:layout_width= "Fill_parent"
android:layout_height= "50DP"
android:layout_gravity= "Center"
android:orientation= "Horizontal" >
<textview
Android:layout_width= "100DP"
android:layout_height= "Wrap_content"
android:layout_marginright= "20DP"
Android:gravity= "Center_vertical|right"
android:text= "Name:"
Android:textsize= "20DP"/>
<edittext
Android:id= "@+id/name"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"/>
</LinearLayout>
<linearlayout
Android:layout_width= "Fill_parent"
android:layout_height= "50DP"
android:layout_gravity= "Center"
android:orientation= "Horizontal" >
<textview
Android:layout_width= "100DP"
android:layout_height= "Wrap_content"
Android:gravity= "Center_vertical|right"
android:layout_marginright= "20DP"
android:text= "mobile phone Number:"
Android:textsize= "20DP"/>
<edittext
Android:id= "@+id/phone"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"/>
</LinearLayout>
<linearlayout
Android:layout_width= "Fill_parent"
android:layout_height= "50DP"
android:layout_gravity= "Center"
android:gravity= "Center"
android:orientation= "Horizontal" >
<button
Android:id= "@+id/save"
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
android:text= "Save"
Android:textsize= "20SP"
/>
<button
Android:id= "@+id/cancel"
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:text= "Cancel"
android:layout_marginleft= "30DP"
Android:textsize= "20SP"
/>
</LinearLayout>
</LinearLayout>
Contact Detail Interface:
<?xml version= "1.0" encoding= "Utf-8"?>
<relativelayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
Android:layout_marginbottom= "10DP"
android:layout_marginleft= "10DP"
android:layout_marginright= "10DP"
android:layout_margintop= "10DP"
Android:background= "@android: Color/darker_gray" >
<textview
Android:id= "@+id/tv_name"
Android:layout_width= "80DP"
android:layout_height= "Wrap_content"
android:layout_margintop= "20DP"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical|right"
android:text= "Name:"
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/et_name"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
android:layout_aligntop= "@+id/tv_name"
android:layout_torightof= "@+id/tv_name"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical"
Android:text= ""
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/tv_phone"
Android:layout_width= "80DP"
android:layout_height= "Wrap_content"
android:layout_below= "@+id/tv_name"
android:layout_margintop= "20DP"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical|right"
android:text= "mobile phone Number:"
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/et_phone"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
android:layout_aligntop= "@+id/tv_phone"
android:layout_torightof= "@+id/tv_phone"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical"
Android:text= ""
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/tv_email"
Android:layout_width= "80DP"
android:layout_height= "Wrap_content"
android:layout_below= "@+id/tv_phone"
android:layout_margintop= "20DP"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical|right"
android:text= "Email:"
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/et_email"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
android:layout_aligntop= "@+id/tv_email"
android:layout_torightof= "@+id/tv_email"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical"
Android:text= ""
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/tv_address"
Android:layout_width= "80DP"
android:layout_height= "Wrap_content"
android:layout_below= "@+id/tv_email"
android:layout_margintop= "20DP"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical|right"
android:text= "Address:"
Android:textsize= "20sp"/>
<textview
Android:id= "@+id/et_address"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
android:layout_aligntop= "@+id/tv_address"
android:layout_torightof= "@+id/tv_address"
Android:background= "@android: Color/white"
Android:gravity= "Center_vertical"
Android:text= ""
Android:textsize= "20sp"/>
</RelativeLayout>
The menu you want to use in your program is configured in the menu file:
<?xml version= "1.0" encoding= "Utf-8"?>
<menu xmlns:android= "Http://schemas.android.com/apk/res/android" >
<group android:id= "@+id/group1" >
<item android:id= "@+id/detail" android:title= "Details" ></item>
<item android:id= "@+id/update" android:title= "Modify" ></item>
<item android:id= "@+id/delete" android:title= "Delete" ></item>
</group>
</menu>
(3) Activity code:
List page and Adapter adapter
Contactsactivity.java
Package com.demo.contentprovider;
Import java.util.ArrayList;
Import android.app.Activity;
Import Android.app.AlertDialog;
Import Android.content.ContentResolver;
Import Android.content.DialogInterface;
Import Android.content.DialogInterface.OnClickListener;
Import android.content.Intent;
Import Android.database.Cursor;
Import Android.os.Bundle;
Import Android.provider.ContactsContract;
Import Android.view.Menu;
Import Android.view.MenuItem;
Import Android.view.View;
Import Android.widget.AdapterView;
Import Android.widget.AdapterView.OnItemLongClickListener;
Import Android.widget.ListView;
Import Android.widget.PopupMenu;
Import Android.widget.PopupMenu.OnMenuItemClickListener;
Import Android.widget.Toast;
Import Com.demo.adapter.ContactsAdapter;
Import Com.demo.model.Contact;
/**
* Mobile Contact operation
* @author Yinbenyang
*/
public class Contactsactivity extends activity {
private static final int ADD = 0;
private static final int request_add = 100;
Store a list of contacts
Private arraylist<contact> contactlist = null;
Contact Adapter
Private Contactsadapter adapter;
Private ListView ListView;
pop-up menu
public PopupMenu popupmenu = null;
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.contentprovider);
ListView = (ListView) Findviewbyid (R.id.listview);
Init ();
Listview.setonitemlongclicklistener (New Onitemlongclicklistenerimpl ());
Registerforcontextmenu (listview);
}
----------------------------------------------------Options Menu---------------------------------------------------
@Override
public boolean Oncreateoptionsmenu (Menu menu) {
TODO auto-generated Method Stub
Menu.add (0, add, 0, "add");
return Super.oncreateoptionsmenu (menu);
}
@Override
public boolean onoptionsitemselected (MenuItem item) {
TODO auto-generated Method Stub
Switch (Item.getitemid ()) {
Case ADD:
Intent Intent = new Intent (this, addcontactactivity.class);
Startactivityforresult (Intent, request_add);
Break
Default
Break
}
return true;
}
@Override
protected void Onactivityresult (int requestcode, int resultcode, Intent data) {
TODO auto-generated Method Stub
Switch (requestcode) {
Case Request_add:
Init ();
Break
Default
Break
}
Super.onactivityresult (Requestcode, ResultCode, data);
}
Initialize, get contact
private void init () {
Contentresolver resolver = Getcontentresolver ();
/**
* ContactsContract.Contacts.CONTENT_URI: Mobile phone contact person's uri:content://com.android
*. contacts/contacts
* Sort_key_alt: It holds the name of the contact person Pinyin, such as the contact name is "Li Ming", then Sort_key saved is "Li Li Ming",
* So if you are sorting by Sort_key or Sort_key_alt, you can arrange your contacts in order
*/
Cursor Cursor = Resolver.query (ContactsContract.Contacts.CONTENT_URI,
NULL, NULL, NULL, "Sort_key_alt");
ContactList = new arraylist<contact> ();
while (Cursor.movetonext ()) {
Contact contacts = new Contact ();
String phonenumber = null;
String name = cursor.getstring (cursor
. Getcolumnindex (ContactsContract.Contacts.DISPLAY_NAME));
String ID = cursor.getstring (cursor
. Getcolumnindex (contactscontract.contacts._id));
Cursor phonecursor = Resolver.query (
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, NULL,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "="
+ ID, NULL, NULL);
while (Phonecursor.movetonext ()) {
PhoneNumber = Phonecursor
. getString (Phonecursor
. Getcolumnindex (ContactsContract.CommonDataKinds.Phone.NUMBER));
}
Contact.setid (Integer.parseint (id));
Contact.setname (name);
Contact.setphone (PhoneNumber);
Contactlist.add (contact);
}
adapter = new Contactsadapter (this, contactlist);
Listview.setadapter (adapter);
}
Private class Onitemlongclicklistenerimpl Implements
Onitemlongclicklistener {
@Override
public Boolean Onitemlongclick (adapterview<?> parent, view view,
final int position, long ID) {
Final Contentresolver resolver = Getcontentresolver ();
PopupMenu = new PopupMenu (Contactsactivity.this, ListView);
Popupmenu.getmenuinflater (). Inflate (R.menu.my_menu,
Popupmenu.getmenu ());
Popupmenu.setonmenuitemclicklistener (New Onmenuitemclicklistener () {
@Override
public boolean Onmenuitemclick (MenuItem item) {
Switch (Item.getitemid ()) {
Case R.id.detail:
String id = contactlist.get (position). GetId () + "";
Intent Intent = new Intent (Contactsactivity.this,
Contactdetailactivity.class);
Intent.putextra ("id", id);
StartActivity (Intent);
Break
Case R.id.update:
Toast.maketext (Contactsactivity.this, "perform modify operations",
Toast.length_short). Show ();
Break
Case R.id.delete:
New Alertdialog.builder (Contactsactivity.this)
. Settitle ("? h except Contacts")
. Setmessage ("Are you sure you want to delete this contact?")
. Setpositivebutton (OK), new Onclicklistener () {
@Override
public void OnClick (Dialoginterface dialog,
int which) {
int i = resolver
. Delete (ContactsContract.RawContacts.CONTENT_URI,
contactscontract.data._id
+ " = "
+ contactlist
. Get (position)
. GetId (),
NULL);
Toast.maketext (Contactsactivity.this,
i = = 1? "? h except success! ":" H except?。? quot;
Toast.length_short). Show ();
Init ();
}
})
. Setnegativebutton ("Cancel", new Onclicklistener () {
@Override
public void OnClick (Dialoginterface dialog,
int which) {
Dialog.dismiss ();
}
). Create (). Show ();
Break
Default
Break
}
Toast.maketext (Contactsactivity.this,
"You clicked:" + Item.gettitle (), Toast.length_short)
. Show ();
Popupmenu.dismiss ();
return true;
}
});
Popupmenu.show ();
return true;
}
}
}
/**
* <!--contact-related URI--> content://com.android.contacts/contacts operation data is the contact information URI
* Content://com.android.contacts/data/phones Contact Phone URI
* Content://com.android.contacts/data/emails Contact Email Uri
*/
Contactsadapter.java
Package com.demo.adapter;
Import java.util.ArrayList;
Import Android.content.Context;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.BaseAdapter;
Import Android.widget.TextView;
Import COM.DEMO.CONTENTPROVIDER.R;
Import Com.demo.model.Contact;
/**
* Contact person's Adapter
*
* @author Yinbenyang
*/
public class Contactsadapter extends Baseadapter {
private context;
Private arraylist<contact> listcontact;
Public Contactsadapter (context context, arraylist<contact> listcontact) {
This.context = context;
This.listcontact = Listcontact;
}
@Override
public int GetCount () {
return Listcontact.size ();
}
@Override
Public Object getitem (int position) {
return Listcontact.get (position);
}
@Override
public long getitemid (int position) {
return position;
}
@Override
Public View GetView (int position, View Convertview, ViewGroup parent) {
Viewholder holder = null;
if (Convertview = = null) {
Convertview = View
. Inflate (context, r.layout.listview_contact, null);
Holder = new Viewholder ();
Holder.id = (TextView) Convertview.findviewbyid (r.id.id);
Holder.name = (TextView) Convertview.findviewbyid (r.id.name);
Holder.phone = (TextView) Convertview.findviewbyid (R.id.phone);
Convertview.settag (holder);
} else {
Holder = (viewholder) convertview.gettag ();
}
Contact con = listcontact.get (position);
Holder.id.setText (Con.getid (). toString ());
Holder.name.setText (Con.getname ());
Holder.phone.setText (Con.getphone ());
return convertview;
}
Static Class Viewholder {
TextView ID;
TextView name;
TextView phone;
}
}
Add Contact Activity:
Addcontactactivity.java
Package com.demo.contentprovider;
Import android.app.Activity;
Import Android.content.ContentUris;
Import android.content.ContentValues;
Import Android.net.Uri;
Import Android.os.Bundle;
Import Android.provider.ContactsContract;
Import Android.provider.ContactsContract.CommonDataKinds.Phone;
Import Android.provider.ContactsContract.CommonDataKinds.StructuredName;
Import Android.provider.ContactsContract.Data;
Import android.provider.ContactsContract.RawContacts;
Import Android.view.View;
Import Android.view.View.OnClickListener;
Import Android.widget.Button;
Import Android.widget.EditText;
/**
* Add contact information
* @author Yinbenyang
*
*/
public class Addcontactactivity extends activity implements onclicklistener{
Private EditText Name,phone;
Private Button Save,cancel;
@Override
protected void OnCreate (Bundle savedinstancestate) {
TODO auto-generated Method Stub
Super.oncreate (savedinstancestate);
Setcontentview (r.layout.addcontact);
Name = (edittext) Findviewbyid (r.id.name);
Phone = (edittext) Findviewbyid (R.id.phone);
Save = (Button) Findviewbyid (R.id.save);
Cancel = (Button) Findviewbyid (r.id.cancel);
Save.setonclicklistener (this);
Cancel.setonclicklistener (this);
}
@Override
public void OnClick (View v) {
TODO auto-generated Method Stub
Switch (V.getid ()) {
Case R.id.save:
String _name = Name.gettext (). toString (). ReplaceAll ("", "");
String _phone = Phone.gettext (). toString (). ReplaceAll ("", "");
Contentvalues values = new Contentvalues ();
First, a null value insertion is performed to the Rawcontacts.content_uri to obtain the Rawcontactid returned by the system
Uri Rawcontacturi =getcontentresolver (). Insert (Rawcontacts.content_uri, values);
Long Rawcontactid = Contenturis.parseid (Rawcontacturi);
Go to data table name
Values.clear ();
Values.put (data.raw_contact_id, Rawcontactid);
Set Content Type
Values.put (Data.mimetype, Structuredname.content_item_type);
Set the content name
Values.put (Structuredname.given_name, _name);
Getcontentresolver (). Insert (
ContactsContract.Data.CONTENT_URI, values);
Go to data table in phone numbers
Values.clear ();
Values.put (data.raw_contact_id, Rawcontactid);
Values.put (Data.mimetype, Phone.content_item_type);
Set up phone numbers
Values.put (Phone.number, _phone);
Set up phone types
Values.put (Phone.type, phone.type_mobile);
Getcontentresolver (). Insert (
ContactsContract.Data.CONTENT_URI, values);
This.finish ();
Break
Case R.id.cancel:
This.finish ();
Break
Default
Break
}
}
}
Contact Details Page:
Contactdetailactivity.java
Package com.demo.contentprovider;
Import android.app.Activity;
Import Android.content.ContentResolver;
Import android.content.Intent;
Import Android.database.Cursor;
Import Android.os.Bundle;
Import Android.provider.ContactsContract;
Import Android.widget.TextView;
/**
* Contact details
*
* @author Yinbenyang
*
*/
public class Contactdetailactivity extends activity {
Private TextView Et_name, Et_phone, Et_email, et_address;
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.contactdetail);
Et_name = (TextView) Findviewbyid (r.id.et_name);
Et_phone = (TextView) Findviewbyid (R.id.et_phone);
Et_email = (TextView) Findviewbyid (R.id.et_email);
Et_address = (TextView) Findviewbyid (r.id.et_address);
Intent Intent = Getintent ();
String id = intent.getstringextra ("id");
Contentresolver resolver = Getcontentresolver ();
Find Names
Cursor namecursor = Resolver.query (
ContactsContract.Contacts.CONTENT_URI,
Null
contactscontract.contacts._id + "=" + ID,
NULL, NULL);
while (Namecursor.movetonext ()) {
Et_name.settext (Namecursor.getstring (Namecursor.getcolumnindex (ContactsContract.Contacts.DISPLAY_NAME)));
}
Find mobile phone number
Cursor phonecursor = Resolver.query (
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, NULL,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + ID,
NULL, NULL);
while (Phonecursor.movetonext ()) {
Et_phone.settext (Phonecursor.getstring (phonecursor
. Getcolumnindex (ContactsContract.CommonDataKinds.Phone.NUMBER));
}
Find Mailboxes
Cursor emailcursor = Resolver.query (
ContactsContract.CommonDataKinds.Email.CONTENT_URI, NULL,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=" + ID,
NULL, NULL);
while (Emailcursor.movetonext ()) {
Et_email.settext (Emailcursor.getstring (emailcursor
. Getcolumnindex (ContactsContract.CommonDataKinds.Email.DATA));
}
Find Addresses
Cursor addresscursor = Resolver.query (
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
Null
ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID
+ "=" + ID, NULL, NULL);
while (Addresscursor.movetonext ()) {
Et_address
. SetText (Addresscursor.getstring (addresscursor
. Getcolumnindex (ContactsContract.CommonDataKinds.StructuredPostal.DATA));
}
}
}
The final effect figure is as follows. You can implement the Add, delete, and modify functions of a contact: