summaryrefslogtreecommitdiffstats
path: root/docs/html/resources/articles/contacts.jd
diff options
context:
space:
mode:
authorScott Main <smain@google.com>2012-06-21 17:14:39 -0700
committerScott Main <smain@google.com>2012-06-21 21:27:30 -0700
commit50e990c64fa23ce94efa76b9e72df7f8ec3cee6a (patch)
tree52605cd25e01763596477956963fabcd087054b0 /docs/html/resources/articles/contacts.jd
parenta2860267cad115659018d636bf9203a644c680a7 (diff)
downloadframeworks_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.jd424
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 &mdash;
-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> &mdash; normal mode, automatic
-aggregation is allowed.</li>
-<li><code>AGGREGATION_MODE_DISABLED</code> &mdash; automatic aggregation is not
-allowed. The raw contact will not be aggregated.</li>
-<li><code>AGGREGATION_MODE_SUSPENDED</code> &mdash; 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 &mdash; 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>&lt;uses-sdk&gt;</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>&lt;uses-sdk&gt;</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>&lt;uses-sdk&gt;</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 {
- &#64;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 &lt; Build.VERSION_CODES.ECLAIR) {
- className = "ContactAccessorOldApi";
- } else {
- className = "ContactAccessorNewApi";
- }
- try {
- Class&lt;? extends ContactAccessor&gt; 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>