- Using content providers to read contacts
- Inserting contacts with content providers
- The principle of the content observer
- Use the Content Viewer to monitor the System application database or its own application database changes
Using content providers to read contacts
Reading a contact is a lot more complicated than reading a text message, so let's step through it.
Take a look at the contact's database, where it is located!
Since it's complicated, let's take a step-by-step analysis, we'll contacts2.db
export it to the computer and open it using the SQLite database software. You can see a whole bunch of tables and views, and of course we only use three of them. respectively raw_contacts
, and data
, mimetypes
respectively, store the contact ID, contact data, contact data corresponding to the Mimie type.
Let's take a look at the first raw_contacts
table.
The column in this table stores the ID of the contact_id
contact in your phone. As you can see from the figure above, there are two contacts in the phone.
Now look at the data
table.
In this table, we are most concerned about three columns mimetype_id
, raw_contact_id
and data1
. mimetype_id
It is the primary key ID of the table, and the mimetype
corresponding raw_contact_id
column is the one raw_contact
contact_id
. So data1
what does the column represent?
You guessed well, that is, the data of our contact person. Horizontally, the raw_contact_id
same row data1
column data makes up a contact's data.
Let's take a look at mimetypes
the table.
is also relatively simple, different mimetype
content represents the different data types, such as: Phone number, name, email and so on.
Looks very troublesome appearance, seemingly also need to tell the data
table and the mimetypes
table union query only then. But instead of being so troublesome, the view that Google engineers have prepared for us has view_data
already data
mimetypes
linked up with two of tables of data. Let's see what's inside.
After understanding the view structure, we contact_id
can get the content and content type of the data by querying it.
After analyzing the contact's table, the next step is to use the content resolver to query, as before, still know the hostname and path . Follow me to look at the source code, this time the contact app content provider's path is android4.4\packages\providers\contactsprovider
. To open the manifest file, you can see the following information:
<provider android:name = "ContactsProvider2" android:authorities =" contacts;com.android.contacts " Span class= "Hljs-attribute" >android:label = "@string/provider_label" android:multiprocess = "false" android:exported =" true " Android:readpermission = "Android.permission.READ_CONTACTS" android:writepermission =" Android.permission.WRITE_CONTACTS " ; </provider ;
The hostname is: com.andriod.contacts
, remember not to forget to add read contacts and write contact permissions.
Open src\com\android\providers\contacts\ContactsProvider2.java
the file again and see what the path is.
static { // Contacts URI matching table "raw_contacts", RAW_CONTACTS); "raw_contacts/#", RAW_CONTACTS_ID); ... ... "data", DATA); "data/#", DATA_ID); ... ...}
As you can see, the path to the view is the raw_contacts
raw_contacts
path to the View data
table data
.
-
When everything is ready to go, step into the code.
-
① The ID collection of the contact in the Raw_contacts table
-
② Filter by Contact ID, in View_data view, find MimeType and data1
Here's the code:
//Find out the collection of contact IDs in the Raw_contacts tableUri Rawcontactsuri = Uri.parse ("Content://com.android.contacts/raw_contacts"); Uri Viewdatauri = Uri.parse ("Content://com.android.contacts/data"); Cursor rawcontactscursor = Getcontentresolver (). Query (Rawcontactsuri,NULL,NULL,NULL,NULL);if(Rawcontactscursor! =NULL) { while(Rawcontactscursor.movetonext ()) {intColumnIndex = Rawcontactscursor.getcolumnindex ("contact_id"); String contact_id = rawcontactscursor.getstring (columnindex);//SYSTEM.OUT.PRINTLN ("Contact ID:" + contact_id); //With contact ID as filter, in View_data view, find MimeType and Data1Cursor viewdatacursor = Getcontentresolver (). Query (Viewdatauri,NewString[] {"MimeType","Data1"},"contact_id=?",NewString[] {contact_id},NULL);if(Viewdatacursor! =NULL) { while(Viewdatacursor.movetonext ()) {String mimetype = viewdatacursor.getstring (0); String data1 = viewdatacursor.getstring (1);if("Vnd.android.cursor.item/phone_v2". Equals (MimeType)) {System.out.println ("Contact ID:"+ contact_id +", Phone:"+ data1); }Else if("Vnd.android.cursor.item/email_v2". Equals (MimeType)) {System.out.println ("Contact ID:"+ contact_id +", Email:"+ data1); }Else if("Vnd.android.cursor.item/name". Equals (MimeType)) {System.out.println ("Contact ID:"+ contact_id +", contact person Name:"+ data1); }} viewdatacursor.close (); }} rawcontactscursor.close ();}
Inserting contacts with content providers
-
Inserting a contact is divided into the following steps:
-
① manually inserting contacts id;id The value of the total number of entries in the database plus 1;
-
② the
data
contact data into the table in turn.
The overall code is still relatively clear, please look at it:
String name = Et_name.gettext (). toString (). Trim (); String phone = Et_phone.gettext (). toString (). Trim ();intcontact_id =0; Uri Rawcontactsuri = Uri.parse ("Content://com.android.contacts/raw_contacts"); Uri Viewdatauri = Uri.parse ("Content://com.android.contacts/data");///manually inserting contacts Id;id value is the total number of entries in the database plus 1;Cursor rawcontactscursor = Getcontentresolver (). Query (Rawcontactsuri,NULL,NULL,NULL,NULL);if(Rawcontactscursor! =NULL) {intCount = Rawcontactscursor.getcount (); contact_id = Count +1; Rawcontactscursor.close ();}//Insert Contact IDContentvalues values =NewContentvalues (); Values.put ("contact_id", contact_id); Getcontentresolver (). Insert (Rawcontactsuri, values);//Insert contact data into the ' data ' table in turn. Contentvalues namevalues =NewContentvalues (); Namevalues.put ("raw_contact_id", contact_id); Namevalues.put ("MimeType","Vnd.android.cursor.item/name"); Namevalues.put ("Data1", name); Getcontentresolver (). Insert (Viewdatauri, namevalues); Contentvalues phonevalues =NewContentvalues ();p honevalues.put ("raw_contact_id", contact_id);p honevalues.put ("MimeType","Vnd.android.cursor.item/phone_v2");p Honevalues.put ("Data1", phone); Getcontentresolver (). Insert (Viewdatauri, phonevalues);
All of these are sample code, and there's a lot more work to do if you want to actually use it.
The principle of the content observer
contentobserver--content Observer, the purpose is to observe (capture) a particular URI caused by the changes in the database, and then do some corresponding processing, it is similar to the database technology triggers (Trigger), when the Contentobserver observed by the URI changes , it will be triggered.
-
The use of Contentobserver is mainly the case of both:
-
It is not economical and time-consuming to use a thread to operate a database or a data ① that requires frequent detection;
-
② in the case of users do not know the database to do some events, such as: Quietly send information, refuse to accept SMS blacklist, etc.;
Use the Content Viewer to monitor the System application database or its own application database changes
Let's give a simple example here. Bo Master's knowledge is too shallow, just browsed some people on the Internet to write the content of the observer's blog, feel that they will be too few things. A little summary. When you use it later, carefully summarize it.
Use observer to monitor system application changes
Listen to the changes in the database, mainly using the ContentResler
methods in the class registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
. The first parameter is the URI we watch, and the second argument is true to match all addresses that begin with the URI we specify, and the third parameter is our observer.
Suppose we want to listen to the changes in the system SMS database, you can do this:
Uri uri = Uri.parse("content://sms"truenew ContentObserver(new Handler()) { @Override publicvoidonChange(boolean selfChange) { super.onChange(selfChange); System.out.println("短信内容发生改变了"); }});
Already know how to monitor the change of a URI, listen to our own application database changes, only need to modify the URI just a bit. However, there is one more step, and when we go through the content provider to access the existing data, we also need to notify, so that the viewer can receive content changes in the message.
Here's how to use it ContentReslover
notifyChange(Uri uri, ContentObserver observer)
.
// 提供给外部应用调用的查询方法@Overridepublicquery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { int MATCH_CODE = MURI_MATCHER.match(uri); if (MATCH_CODE == QUERY_SUCCESS) { // 大喊一声,数据发生改变了 null); returnnullnull, sortOrder); } returnnull;}
These two blog posts are relatively hasty, please include more.
Android Basic Note (14)-content provider reads a contact