Android basic notes (14)-content provider reading contacts, android providers
- Use the content provider to read contacts
- Insert a contact using the content provider
- Principle of content observer
- Use content observer to monitor changes in the system application database or your own application database
Use the content provider to read contacts
Reading contacts is much more complicated than reading text messages. Let's take a step.
First, let's take a look at the contact's database, where it is located!
Since it is complicated, let's analyze it step by step.contacts2.db
Export to your computer and open it with SQLite database software. You can see a lot of tables and views. Of course, we only use three tables and views. They areraw_contacts
,data
,mimetypes
The MIMIE type corresponding to the contact ID, contact data, and contact data is stored respectively.
Let's take a look at it one by one. The first israw_contacts
Table.
In this tablecontact_id
The column stores the ID of the contact in the mobile phone. The figure above shows that there are two contacts on the mobile phone.
Next, let's take a look.data
Table.
In this table, we are most concerned about three columns.mimetype_id
,raw_contact_id
Anddata1
. Wheremimetype_id
Yesmimetype
Primary Key ID of the table; correspondingraw_contact_id
Yesraw_contact
Ofcontact_id
Column. Sodata1
What does a column represent?
You guessed it well, that is, the data of our contacts. Horizontally,raw_contact_id
In the same rowdata1
Column data makes up the data of a contact.
Let's take a look.mimetypes
The table.
It is also relatively simple, differentmimetype
Different data types, such as phone number, name, and Email.
It looks very troublesome. It seems I still need to talk about it.data
Table andmimetypes
Table join query is supported. But it doesn't actually need to be so troublesome. Google engineers have already prepared for us.view_data
Viewdata
Andmimetypes
The data of the two tables is joined. Let's take a look at the content.
After understanding the view structure, we usecontact_id
Query to obtain the data content and content type.
After analyzing the contact table, the next step is to use the content parser to query the table.Host NameAndPath. Let me take a look at the source code. The path of the content provider of this contact application isandroid4.4\packages\providers\ContactsProvider
. Open the configuration file and you can see the following information:
<provider android:name="ContactsProvider2" android:authorities="contacts;com.android.contacts" android:label="@string/provider_label" android:multiprocess="false" android:exported="true" android:readPermission="android.permission.READ_CONTACTS" android:writePermission="android.permission.WRITE_CONTACTS"></provider>
Host NameYes:com.andriod.contacts
Remember not to forget to add readContacts and write contacts.
Open againsrc\com\android\providers\contacts\ContactsProvider2.java
File, take a lookPathWhat is it.
static { // Contacts URI matching table matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID); ... ... matcher.addURI(ContactsContract.AUTHORITY, "data", DATA); matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID); ... ...}
You can see, Viewraw_contacts
Israw_contacts
, Viewdata
The table path isdata
.
-
The preparation is complete, so proceed to the Code step.
-
① Query the contact ID set in the raw_contacts table
-
② Use the contact ID as the filter condition. In the view_data view, search for mimetype and data1
The following code is used:
// The ID set Uri rawContactsUri = Uri of the contact in the raw_contacts table. parse ("content: // com. android. contacts/raw_contacts "); Uri viewDataUri = Uri. parse ("content: // com. android. contacts/data "); Cursor rawContactsCursor = getContentResolver (). query (rawContactsUri, null, null); if (rawContactsCursor! = Null) {while (rawContactsCursor. moveToNext () {int columnIndex = rawContactsCursor. getColumnIndex ("contact_id"); String contact_id = rawContactsCursor. getString (columnIndex); // System. out. println ("Contact ID:" + contact_id); // use the contact ID as the filter condition. In the view_data view, find mimetype and data1 Cursor viewDataCursor = getContentResolver (). query (viewDataUri, new String [] {"mimetype", "data1"}, "contact_id =? ", New String [] {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 + ", tel:" + 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 name:" + data1) ;}} viewDataCursor. close () ;}} rawContactsCursor. close ();}
Insert a contact using the content provider
-
Insert a contact in the following steps:
-
① Manually insert the contact ID; the ID value is the total number of items in the Database Plus 1;
-
② Forward
data
Insert contact data in the table.
The overall code is clear. Please refer to the following code:
String name = et_name.getText (). toString (). trim (); String phone = et_phone.getText (). toString (). trim (); int contact_id = 0; Uri rawContactsUri = Uri. parse ("content: // com. android. contacts/raw_contacts "); Uri viewDataUri = Uri. parse ("content: // com. android. contacts/data "); // manually insert the contact ID; the ID value is the total number of entries in the database plus 1; Cursor rawContactsCursor = getContentResolver (). query (rawContactsUri, null); if (rawContac TsCursor! = Null) {int count = rawContactsCursor. getCount (); contact_id = count + 1; rawContactsCursor. close () ;}// Insert the contact IDContentValues values = new ContentValues (); values. put ("contact_id", contact_id); getContentResolver (). insert (rawContactsUri, values); // insert the contact data to the 'data' table in sequence. ContentValues nameValues = new ContentValues (); 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 = new ContentValues (); phoneValues. put ("raw_contact_id", contact_id); phoneValues. put ("mimetype", "vnd. android. cursor. item/phone_v2 "); phoneValues. put ("data1", phone); getContentResolver (). insert (viewDataUri, phoneValues );
All of the above are sample code, which requires a lot of work to be done in actual use.
Principle of content observer
ContentObserver-content observer, which is used to observe (capture) Changes in the database caused by a specific Uri and then perform corresponding processing. It is similar to a Trigger in database technology ), when the Uri observed by ContentObserver changes, it is triggered.
-
ContentObserver:
-
① Whether the database or data that needs to be frequently checked has changed. It is very economic and time-consuming to operate using threads;
-
② When the user is not aware of the database, perform some events, such as: quietly sending messages, rejecting text message blacklists, etc;
Use content observer to monitor changes in the system application database or your own application database
Here is a simple example. The knowledge of the bloggers is still too low. I just browsed the blogs of content observers written by some people on the internet and felt that I still had too few things. Summary. We will make a careful summary later.
Monitor System Application changes with the observer
Monitors database changes, mainly usedContentResler
ClassregisterContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
Method. The first parameter is the Uri we monitor. When the second parameter is true, it will match all the addresses starting with the Uri we specified. The third parameter is our observer.
Suppose we want to monitor the changes in the system's SMS database, we can do this:
Uri uri = Uri. parse ("content: // sms"); getContentResolver (). registerContentObserver (uri, true, new ContentObserver (new Handler () {@ Override public void onChange (boolean selfChange) {super. onChange (selfChange); System. out. println ("the text message content has changed ");}});
After you know how to monitor the changes of a Uri, you only need to modify the Uri to listen to the changes in our own application database. However, here is another step. When we access existing data through the content provider, we need to notify the observer to receive the message with the changed content.
Here we useContentReslover
InnotifyChange(Uri uri, ContentObserver observer)
Method.
// Query method provided to external applications @ Overridepublic Cursor query (Uri uri, String [] projection, String selection, String [] selectionArgs, String sortOrder) {int MATCH_CODE = MURI_MATCHER.match (uri); if (MATCH_CODE = QUERY_SUCCESS) {// when a shout is made, the data changes getContext (). getContentResolver (). notifyChange (uri, null); return db. query (ACCOUNT, projection, selection, selectionArgs, null, null, sortOrder);} return null ;}
These two blogs are too hasty to write. Please include them.