Chapter 5. Querying the Contacts Table

Earlier in this book, we looked at how we could build a SQLite database for our application by overriding the SQLiteOpenHelper class. Then, we extended our understanding of databases on Android by introducing the ContentProvider class, which allowed us to expose our SQLite databases to external applications, and more generally to the Android OS itself.

However, while knowing how to design and implement your own database is a powerful skill to have, knowing how to leverage existing data on the user's device can be just as beneficial. Oftentimes, this will mean querying existing content providers for various types of data, but one especially important content provider – and by far the most commonly queried content provider - is the Contacts content provider.

In this chapter, we'll start by exploring the structure of the Contacts content provider (that is, its schema) and then look at the various ways to query for contacts and their associated metadata.

Structure of the Contacts content provider

Understanding the schema of the Contacts content provider is half of the challenge. Because of the wealth of data that can potentially be associated with a contact, much work had to be done in designing a schema which would be both flexible and powerful enough to meet every user's needs. In the following table, I've sketched out how this schema is laid out, and from there we'll examine how the schema works at a high level, before diving into each table of the schema:

Structure of the Contacts content provider

So here you have it – doesn't look too daunting right? Of course, the columns shown previously are just a subset of the actual columns in each table, but it should hopefully be enough to give you an idea of how these tables all work together. If you'd like to see all the columns in each table, I invite you to look at the following links:

http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html

http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html

http://developer.android.com/reference/android/provider/ContactsContract.Data.html

Let's think about the schema from a high level first. At the top, we have the Contacts table. In previous versions of Android (API levels 4 and under), this was more or less all you had. It was just the typical, intuitive, Contacts table, which contained each contact's unique ID as well as their names, phone numbers, e-mails, and so on.

Then things got complicated. Suddenly, Android 2.0 (API levels 5 and up) came out and users were allowed to sync their contacts with Facebook, with Twitter, with Google, along with numerous other services. Does it still make sense to have just a simple Contacts table? Would each contact for each source be its own separate row? And how would we know which rows are actually referring to the same contact?

Because of this, Google had to develop a second layer of tables which reference the Contacts table – these tables are called Raw Contacts. Every contact the user has is an aggregation of raw contacts, where each raw contact represents a single contact from a specific source. So, say you had a friend and you've synced that contact with both Facebook and Twitter. This friend would then have two Raw Contact tables, one describing his/her metadata from Facebook and the other describing his/her metadata from Twitter. Both of these raw contacts would then both point to a single entry in the Contacts table.

But wait, whereas before each contact's metadata was more or less limited to a few phone numbers and a few e-mails, now there's an enormous amount of metadata available for each contact, thanks to social networking. So how would we store all this metadata? Each contact's latest status messages or latest tweets? Would we just have one enormous Raw Contacts table with thirty or so columns?

Preferably no – that's probably not a good use of memory, as that table would likely be fairly sparse. So instead, the team at Google decided to create a third layer of tables, known as the Data tables. These Data tables all reference a raw contact, which again, references a contact. And so that's essentially how a contact is described in the Android OS – a contact is an aggregation of raw contacts which are each specific to a source (that is, Facebook or Twitter) and each raw contact is an aggregation of separate data tables where each data table contains a certain type of data (that is, phone numbers, e-mails, status messages, and so on). That's the high-level picture of what's happening, and in the next section we'll look at how you actually query these tables for common fields, such as phone numbers and e-mails.

Now, there are many technical details that fully describe what's happening in the schema, but for now I'll end this section with a brief discussion of how this aggregation between raw contacts actually works.

The system automatically aggregates raw contacts, and so each time you create a new contact or sync a new account to an existing contact, that raw contact is created with aggregation mode set to DEFAULT, which tells the system to aggregate this raw contact with other raw contacts referencing the same contact. However, you can explicitly define what kind of aggregation you want for that raw contact and the options are as follows:

  • AGGREGATION_MODE_DEFAULT – The default state, where automatic aggregation is allowed
  • AGGREGATION_MODE_DISABLED Automatic aggregation is not allowed and the raw contact will not be aggregated
  • AGGREGATION_MODE_SUSPENDED – Automatic aggregation is deactivated, however, if the raw contact was previously aggregated, then it will remain aggregated

These are the three modes of aggregation, which you can update and adjust for each raw contact. As for how the aggregation is done, it's primarily done by matching names and/or nicknames, and if names are not present, then the match is attempted using phone numbers and e-mails.

By now you should have a decent understanding of what the Contacts content provider looks like, and so we'll move on to looking at some code!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.34.169