diff options
author | Scott Main <smain@google.com> | 2012-06-21 17:14:39 -0700 |
---|---|---|
committer | Scott Main <smain@google.com> | 2012-06-21 21:27:30 -0700 |
commit | 50e990c64fa23ce94efa76b9e72df7f8ec3cee6a (patch) | |
tree | 52605cd25e01763596477956963fabcd087054b0 /docs/html/resources/articles/contacts.jd | |
parent | a2860267cad115659018d636bf9203a644c680a7 (diff) | |
download | frameworks_base-50e990c64fa23ce94efa76b9e72df7f8ec3cee6a.zip frameworks_base-50e990c64fa23ce94efa76b9e72df7f8ec3cee6a.tar.gz frameworks_base-50e990c64fa23ce94efa76b9e72df7f8ec3cee6a.tar.bz2 |
Massive clobber of all HTML files in developer docs for new site design
Change-Id: Idc55a0b368c1d2c1e7d4999601b739dd57f08eb3
Diffstat (limited to 'docs/html/resources/articles/contacts.jd')
-rw-r--r-- | docs/html/resources/articles/contacts.jd | 424 |
1 files changed, 0 insertions, 424 deletions
diff --git a/docs/html/resources/articles/contacts.jd b/docs/html/resources/articles/contacts.jd deleted file mode 100644 index 374587b..0000000 --- a/docs/html/resources/articles/contacts.jd +++ /dev/null @@ -1,424 +0,0 @@ -page.title=Using the Contacts API -parent.title=Articles -parent.link=../browser.html?tag=article -@jd:body - -<p>Starting from Android 2.0 (API Level 5), the Android platform provides an -improved Contacts API for managing and integrating contacts from multiple -accounts and from other data sources. To handle overlapping data from multiple -sources, the contacts content provider aggregates similar contacts and presents -them to users as a single entity. This article describes how to use the new API -to manage contacts.</p> - -<p>The new Contacts API is defined in the -{@link android.provider.ContactsContract android.provider.ContactsContract} -and related classes. The older API is still supported, although deprecated. -If you have an existing application that uses the older API, -see <a href="#legacy">Considerations for legacy apps</a>, below, for ideas -on how to support the Contacts API in your app.</p> - -<p>If you'd like to look at an applied example of how to use the new Contacts -API, including how to support both the new and older API in a single app, -please see the <a -href="{@docRoot}resources/samples/BusinessCard/index.html">Business Card -sample application</a>.</p> - -<h3>Data structure of Contacts</h3> - -<p>In the new Contacts API, data is laid out in three primary tables: -<em>contacts</em>, <em>raw contacts</em>, and <em>data</em>, a structure that -is slightly different from that used in the older API. The new structure -allows the system to more easily store and manage information for a -specific contact from multiple contacts sources. </p> - -<img style="margin: 0px auto 10px; display: block; text-align: center; width: 471px; height: 255px;" src="images/contacts-2.png" alt="" border="0"> - -<ul> -<li><code>Data</code> is a generic table that stores all of the data points -associated with a raw contact. Each row stores data of a specific kind — -for example name, photo, email addresses, phone numbers, and group memberships. -Each row is tagged with a MIME type to identify what type of data it can -contain, across the entire column. Columns are generic and the type of data they -contain is determined by the kind of data stored in each row. For example, if a -row's data kind is <code>Phone.CONTENT_ITEM_TYPE</code>, then the first column -stores the phone number, but if the data kind is -<code>Email.CONTENT_ITEM_TYPE</code>, then the column stores the email address. - -<p>The {@link android.provider.ContactsContract.CommonDataKinds ContactsContract.CommonDataKinds} -class provides subclasses corresponding to common MIME types for contacts data. -If needed, your application or other contacts sources can define additional MIME -types for data rows. For more information about the Data table and examples of -how to use it, see {@link android.provider.ContactsContract.Data android.provider.ContactsContract.Data}.</p></li> - -<li>A row in the <code>RawContacts</code> table represents the set of -<code>Data</code> and other information describing a person and associated with -a single contacts source. For example, a row might define the data associated -with a person's Google or Exchange account or Facebook friend. For more -information, see -{@link android.provider.ContactsContract.RawContacts ContactsContract.RawContacts}.</p> - -<li>A row in the <code>Contacts</code> table represents an aggregate of one or -more <code>RawContacts</code> describing the same person (or entity). - -<p>As mentioned above, the Contacts content provider automatically aggregates -Raw Contacts into a single Contact entry, where possible, since common data -fields (such as name or email address) are likely to be stored in each raw -contact. Since the aggregation logic maintains the entries in the Contact rows, -the entries can be read but should not be modified. See the section <a -href="#aggregation">Aggregation of contacts</a>, below, for more details, -including and information on how to -control aggregation.</li> - -</ul> - -<p>When displaying contacts to users, applications should typically operate on -the Contacts level, since it provides a unified, aggregated view of contacts -from various underlying sources. </p> - -<h4>Example: Inserting a Phone Number</h4> - -<p>To insert a phone number using the new APIs you'll need the ID of the Raw -Contact to attach the phone number to, then you'll need to create a Data -row:</p> - -<pre>import android.provider.ContactsContract.CommonDataKinds.Phone; -... -ContentValues values = new ContentValues(); -values.put(Phone.RAW_CONTACT_ID, rawContactId); -values.put(Phone.NUMBER, phoneNumber); -values.put(Phone.TYPE, Phone.TYPE_MOBILE); -Uri uri = getContentResolver().insert(Phone.CONTENT_URI, values);</pre> - - -<h3 id="aggregation">Aggregation of contacts</h3> - -<p>When users sync contacts from multiple sources, several contacts might refer -to the same person or entity, but with slightly different (or overlapping) data. - For example, "Bob Parr" might be a user's co-worker and also his personal -friend, so the user might have his contact information stored in both a -corporate email account and a personal account. To provide a simplified view for -the user, the system locates such overlapping contacts and combines them into a -single, aggregate contact. </p> - -<p>The system automatically aggregates contacts by default. However, if needed, -your application can control how the system handles aggregation or it can -disable aggregation altogether, as described in the sections below.</p> - -<h4>Automatic aggregation</h4> - -<p>When a raw contact is added or modified, the system looks for matching -(overlapping) raw contacts with which to aggregate it. It may not find any -matching raw contacts, in which case it will create an aggregate contact that -contains just the original raw contact. If it finds a single match, it creates a -new contact that contains the two raw contacts. And it may even find multiple -similar raw contacts, in which case it chooses the closest match. </p> - -<p>Two raw contacts are considered to be a match if at least one of these -conditions is met:</p> - -<ul> -<li>They have matching names.</li> -<li>Their names consist of the same words but in different order -(for example, "Bob Parr" and "Parr, Bob")</li> -<li>One of them has a common short name for the other (for example, -"Bob Parr" and "Robert Parr")</li> -<li>One of them has just a first or last name and it matches the other -raw contact. This rule is less reliable, so it only applies if the two -raw contacts are also sharing some other data like a phone number, an -email address or a nickname (for example, Helen ["elastigirl"] = Helen -Parr ["elastigirl"])</li> -<li>At least one of the two raw contacts is missing the name altogether -and they are sharing a phone number, an email address or a nickname (for -example, Bob Parr [incredible@android.com] = incredible@android.com).</li> -</ul> - -<p>When comparing names, the system ignores upper/lower case differences -(Bob=BOB=bob) and diacritical marks (Hélène=Helene). When comparing two -phone numbers the system ignores special characters such as "*", "#", -"(", ")", and whitespace. Also if the only difference between two numbers -is that one has a country code and the other does not, then the system -considers those to be a match (except for numbers in the Japan country code).</p> - -<p>Automatic aggregation is not permanent; any change of a constituent raw -contact may create a new aggregate or break up an existing one.</p> - -<h4>Explicit aggregation</h4> - -<p>In some cases, the system's automatic aggregation may not meet the -requirements of your application or sync adapter. There are two sets of APIs you -can use to control aggregation explicitly: <em>aggregation modes</em> allow you -to control automatic aggregation behaviors and <em>aggregation exceptions</em> -allow you to override automated aggregation entirely. - -<p><strong>Aggregation modes</strong></p> - -<p>You can set an aggregation mode for each raw contact individually. To do so, -add a mode constant as the value of the <code>AGGREGATION_MODE column</code> in -the <code>RawContact</code> row. The mode constants available include: </p> - -<ul> -<li><code>AGGREGATION_MODE_DEFAULT</code> — normal mode, automatic -aggregation is allowed.</li> -<li><code>AGGREGATION_MODE_DISABLED</code> — automatic aggregation is not -allowed. The raw contact will not be aggregated.</li> -<li><code>AGGREGATION_MODE_SUSPENDED</code> — automatic aggregation is -deactivated. If the raw contact is already a part of an aggregated contact when -aggregation mode changes to suspended, it will remain in the aggregate, even if -it changes in such a way that it no longer matches the other raw contacts in the -aggregate.</li> -</ul> - -<p><strong>Aggregation exceptions</strong></p> - -<p>To keep two raw contacts unconditionally together or unconditionally apart, -you can add a row to the -{@link android.provider.ContactsContract.AggregationExceptions} table. Exceptions -defined in the table override all automatic aggregation rules. </p> - - -<h3>Loookup URI</h3> - -<p>The new Contacts API introduces the notion of a lookup key for a contact. If -your application needs to maintain references to contacts, you should use lookup -keys instead of the traditional row ids. You can acquire a lookup key from the -contact itself, it is a column on the -{@link android.provider.ContactsContract.Contacts} table. Once you have a lookup key, -you can construct a URI in this way:</p> - -<pre>Uri lookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey)</pre> - -<p>and use it like you would use a traditional content URI, for example: </p> - -<pre>Cursor c = getContentResolver().query(lookupUri, new String[]{Contacts.DISPLAY_NAME}, ...); -try { - c.moveToFirst(); - String displayName = c.getString(0); -} finally { - c.close(); -}</pre> - -<p>The reason for this complication is that regular contact row IDs are -inherently volatile. Let's say your app stored a long ID of a contact. Then the -user goes and manually joins the contact with some other contact. Now there is a -single contact where there used to be two, and the stored long contact ID points -nowhere. - -<p>The lookup key helps resolve the contact in this case. The key is a string -that concatenates the server-side identities of the raw contacts. Your -application can use that string to find a contact, regardless whether the raw -contact is aggregated with others or not. </p> - -<p>If performance is a concern for your application, you might want to store -both the lookup and the long ID of a contact and construct a lookup URI out of -both IDs, as shown here:</p> - -<pre>Uri lookupUri = getLookupUri(contactId, lookupKey)</pre> - -<p>When both IDs are present in the URI, the system will try to use the long ID -first. That is a very quick query. If the contact is not found, or if the one -that is found has the wrong lookup key, the content provider will parse the -lookup key and track down the constituent raw contacts. If your app -bulk-processes contacts, you should maintain both IDs. If your app works with a -single contact per user action, you probably don't need to bother with storing -the long ID.</p> - -Android itself uses lookup URIs whenever there is a need to reference a contact, -such as with shortcuts or Quick Contact, and also during editing or even viewing -a contact. The latter case is less obvious — why would a contact ID change -while we are simply viewing the contact? It could change because there might be -a sync going in the background, and the contact might get automatically -aggregated with another while being viewed.</p> - -<p>In summary: whenever you need to reference a contact, we recommend that you -do so by its lookup URI.</p> - - -<h3 id="legacy">Considerations for legacy applications</h3> - -<p>If you have an existing application that uses the older Contacts API, -you should consider upgrading it to use the new API. You have four options: </p> - -<ul> -<li>Leave it as-is and rely on the Contacts compatibility mode.</li> -<li>Upgrade the app and discontinue support of pre-Android 2.0 platforms.</li> -<li>Build a new version of the app for the new API, while keeping the old version available.</li> -<li>Make the app use the right set of APIs depending on the platform where it is deployed. </li> -</ul> - -<p>Let's consider these options one by one.</p> - -<h4>Using compatibility mode</h4> - -<p>Compatibility mode is the easiest option because you just leave the -application as is, and it should run on Android 2.0 as long as it only uses -public APIs. A couple examples of the use of non-public API include the use of -explicit table names in nested queries and the use of columns that were not -declared as public constants in the {@link android.provider.Contacts} class. -</p> - -<p>Even if the application currently runs, you don't want to leave it like this -for long. The main reason is that it will only have access to contacts from one -account, namely the first Google account on the device. If the user opens other -accounts in addition to or instead of a Google account, your application will -not be able to access those contacts.</p> - - -<h4>Upgrading to the new API and dropping support for older platforms</h4> - -<p>If your application will no longer target platforms older than -Android 2.0, you can upgrade to the new API in this way:</p> - -<ul> -<li>Replace all usages of {@link android.provider.Contacts} with calls to new -API. After you are done, you should not see any deprecation warnings during -application build. The new application will be able to take full advantage of -multiple accounts and other new features of Android 2.0. </p> - -<li>In the application's manifest, update (or add) the -<code>android:minSdkVersion</code> attribute to the -<code><uses-sdk></code> element. To use the new Contacts API, you should -set the value of the attribute to "5" (or higher, as appropriate). For more -information about <code>android:minSdkVersion</code>, see the documentation for -the <a -href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a> -element. For more information about the value of the -<code>minSdkVersion</code>, see <a -href="{@docRoot}guide/appendix/api-levels.html">API Levels</a>.</li> -</ul> - -<h4>Maintaining two applications</h4> - -<p>You may decide to have two different applications: one for pre-Android 2.0 -platforms and one for Android 2.0 and beyond. If so, here's what you'll need to do:</p> - -<ul> - <li>Clone your existing app. </li> - <li>Change the old application: </li> - <ul> - <li>At launch time, check the version of the SDK. The version of the SDK -is available as {@link android.os.Build.VERSION#SDK android.os.Build.VERSION.SDK}.</li> - <li>If the SDK version is greater or equal to 5 (Android 2.0), show a dialog -suggesting to the user that it's time to go to Google Play and find a new version of -the app. You can even provide a link to the new app on Google Play (see <a -href="{@docRoot}guide/publishing/publishing.html#marketintent">Using Intents -to Launch Google Play</a>). </li> - </ul> - <li>Change the new application:</li> - <ul> - <li>Replace all usages of the older Contacts API with calls to new API. -The new application will be able to take full advantage of multiple accounts -and other new features of Android 2.0. </li> - <li>Modify that application's AndroidManifest.xml file: </li> - <ul> - <li>Give the application a new name and a new package name. Currently -Google Play does not allow you to have two applications with the same -name/package.</li> - <li>Update (or add) the <code>android:minSdkVersion</code> attribute -to the <code><uses-sdk></code> element. To use the new Contacts API, -you should set the value of the attribute to "5" (or higher, as appropriate).</li> - </ul> - </ul> - <li>Publish both apps on Google Play, the old app one as an upgrade and the -other as new. Make sure to explain the difference between the apps in their -descriptions.</li> -</ul> - -<p>This plan has its disadvantages: </p> - -<ul> -<li>The new application will not be able to read the old application's data. -Application data can only be accessed by code living in the same package. So -databases, shared preferences, and so on, will need to be populated from -scratch.</li> -<li>The upgrade process is too clunky for the user. Some users may choose -to either stay with the crippled old version or uninstall altogether.</li> -</ul> - -<h4>Supporting the old and new APIs in the same application</h4> - -<p>This is a bit tricky, but the result is worth the effort. You can -build a single package that will work on any platform:</p> - -<p>Go through the existing application and factor out all access to -{@link android.provider.Contacts} into one class, such as ContactAccessorOldApi. -For example, if you have code like this: - -<pre> protected void pickContact() { - startActivityForResult(new Intent(Intent.ACTION_PICK, People.CONTENT_URI), 0); - }</pre> - -<p>it will change to:</p> - - -<pre> private final ContactAccessorOldApi mContactAccessor = new ContactAccessorOldApi(); - - void pickContact() { - startActivityForResult(mContactAccessor.getContactPickerIntent(), 0); - }</pre> - -<p>The corresponding method on ContactAccessorOldApi will look like this:</p> - -<pre> public Intent getContactPickerIntent() { - return new Intent(Intent.ACTION_PICK, People.CONTENT_URI); - }</pre> - -<p>Once you are done, you should see deprecation warnings coming only -from ContactAccessorOldApi. </p> - -<p>Create a new abstract class ContactAccessor, make sure the abstract -class has all method signatures from ContactAccessorOldApi. Make -ContactAccessorOldApi extend ContactAccessor:</p> - -<pre> public abstract class ContactAccessor { - public abstract Intent getContactPickerIntent(); - ... - }</pre> - -<p>Create a new subclass of ContactAccessor, ContactAccessorNewApi and -implement all methods using the new API:</p> - -<pre> public class ContactAccessorNewApi extends ContactAccessor { - @Override - public Intent getContactPickerIntent() { - return new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); - } - ... - }</pre> - -<p>At this point, you have two implementations of the same API, one using the -old API and another using the new API. Let's plug them in. Add this code to -the ContactAccessor class:</p> - -<pre> private static ContactAccessor sInstance; - - public static ContactAccessor getInstance() { - if (sInstance == null) { - String className; - int sdkVersion = Integer.parseInt(Build.VERSION.SDK); - if (sdkVersion < Build.VERSION_CODES.ECLAIR) { - className = "ContactAccessorOldApi"; - } else { - className = "ContactAccessorNewApi"; - } - try { - Class<? extends ContactAccessor> clazz = - Class.forName(ContactAccessor.class.getPackage() + "." + className) - .asSubclass(ContactAccessor.class); - sInstance = clazz.newInstance(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - return sInstance; - }</pre> - -<p>Now replace references to ContactsAccessorOldApi with references to -ContactsAccessor:</p> - -<pre> private final ContactAccessor mContactAccessor = ContactAccessor.getInstance();</pre> - -<p>You are done! Now you will want to test on Android 2.0, 1.6 and 1.5.</p> - -<p>We hope you like the new features and APIs we've added to Contacts in -Android 2.0, and we can't wait to see what cool things developers do with -the new APIs.</p> |