Support new intent INVITE_CONTACT introduced in v14

SampleSyncAdapter uses INVITE_CONTACT to add a raw contact to an existing
contact.

INVITE_CONTACT is treated in the save way as ACTION_INSERT, except:
- The incoming intent won't have the account extra, so always use the first
  account found.
- The name field will be prepopulated with the display name of the passed
  account.

Bug 5061956

Change-Id: Ica1263fe54150dbc0e79389ebdf2a0e748a7c840
This commit is contained in:
Makoto Onuki
2011-07-26 13:17:35 -07:00
parent c35d058e8d
commit 23e15c5d41
5 changed files with 135 additions and 7 deletions

View File

@@ -112,6 +112,16 @@
<data
android:mimeType="vnd.android.cursor.item/raw_contact" />
</intent-filter>
<!--
We use the INVITE intent to add a raw contact to an existing contact.
It always comes with a lookup URI.
-->
<intent-filter>
<action
android:name="com.android.contacts.action.INVITE_CONTACT" />
<data
android:mimeType="vnd.android.cursor.item/contact" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -102,4 +102,11 @@
name="menu_done">Done</string>
<string
name="menu_cancel">Cancel</string>
<!-- Strings for contacts.xml -->
<skip />
<!-- The label of the button to add contact to this contact provider -->
<string name="invite_action_label">Add to Sample SyncAdaper</string>
</resources>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/**
* Copyright (c) 2011, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<ContactsAccountType
xmlns:android="http://schemas.android.com/apk/res/android"
editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
inviteContactActionLabel="@string/invite_action_label"
>
<ContactsDataKind
android:mimeType="vnd.android.cursor.item/vnd.samplesyncadapter.profile"
android:icon="@drawable/icon"
android:summaryColumn="data2"
android:detailColumn="data3"
android:detailSocialSummary="true" />
</ContactsAccountType>

View File

@@ -15,12 +15,16 @@
*/
package com.example.android.samplesync.editor;
import com.example.android.samplesync.Constants;
import com.example.android.samplesync.R;
import com.example.android.samplesync.client.RawContact;
import com.example.android.samplesync.platform.BatchOperation;
import com.example.android.samplesync.platform.ContactManager;
import com.example.android.samplesync.platform.ContactManager.ContactQuery;
import com.example.android.samplesync.platform.ContactManager.EditorQuery;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
@@ -29,6 +33,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
@@ -86,8 +91,8 @@ public class ContactEditorActivity extends Activity {
mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
mEmailEditText = (EditText)findViewById(R.id.editor_email);
// Figure out whether we're creating a new contact (ACTION_INSERT) or editing
// an existing contact.
// Figure out whether we're creating a new contact (ACTION_INSERT), editing
// an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
Intent intent = getIntent();
String action = intent.getAction();
if (Intent.ACTION_INSERT.equals(action)) {
@@ -100,6 +105,24 @@ public class ContactEditorActivity extends Activity {
finish();
}
setAccountName(accountName);
} else if (ContactsContract.Intents.INVITE_CONTACT.equals(action)) {
// Adding to an existing contact.
mIsInsert = true;
// Use the first account found.
Account[] myAccounts = AccountManager.get(this).getAccountsByType(
Constants.ACCOUNT_TYPE);
if (myAccounts.length == 0) {
Log.e(TAG, "Account not configured");
finish();
}
setAccountName(myAccounts[0].name);
Uri lookupUri = intent.getData();
if (lookupUri == null) {
Log.e(TAG, "Contact lookup URI is required");
finish();
}
startLoadContactEntity(lookupUri);
} else {
// We're editing an existing contact. Load in the data from the contact
// so that the user can edit it.
@@ -163,7 +186,7 @@ public class ContactEditorActivity extends Activity {
* successfully loaded from the Contacts data provider.
*/
public void onRawContactEntityLoaded(Cursor cursor) {
while (cursor.moveToNext()) {
if (cursor.moveToFirst()) {
String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
@@ -184,6 +207,23 @@ public class ContactEditorActivity extends Activity {
}
}
/**
* Create an AsyncTask to load the contact from the Contacts data provider
*/
private void startLoadContactEntity(Uri lookupUri) {
new LoadContactTask().execute(lookupUri);
}
/**
* Called by the LoadContactTask when the contact information has been
* successfully loaded from the Contacts data provider.
*/
public void onContactEntityLoaded(Cursor cursor) {
if (cursor.moveToFirst()) {
mNameEditText.setText(cursor.getString(ContactQuery.COLUMN_DISPLAY_NAME));
}
}
/**
* Save the updated contact data. We actually take two different actions
* depending on whether we are creating a new contact or editing an
@@ -212,6 +252,7 @@ public class ContactEditorActivity extends Activity {
*/
private void setAccountName(String accountName) {
mAccountName = accountName;
Log.i(TAG, "account=" + mAccountName);
if (accountName != null) {
TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
if (accountNameLabel != null) {
@@ -286,12 +327,11 @@ public class ContactEditorActivity extends Activity {
@Override
protected void onPostExecute(Cursor cursor) {
if (cursor == null) return;
// After we've successfully loaded the contact, call back into
// the ContactEditorActivity so we can update the UI
try {
if (cursor != null) {
onRawContactEntityLoaded(cursor);
}
onRawContactEntityLoaded(cursor);
} finally {
cursor.close();
}
@@ -366,4 +406,25 @@ public class ContactEditorActivity extends Activity {
onContactSaved(result);
}
}
/**
* Loads contact information by a lookup URI.
*/
public class LoadContactTask extends AsyncTask<Uri, Void, Cursor> {
@Override
protected Cursor doInBackground(Uri... params) {
return getContentResolver().query(params[0], ContactQuery.PROJECTION, null, null, null);
}
@Override
protected void onPostExecute(Cursor cursor) {
if (cursor == null) return;
try {
onContactEntityLoaded(cursor);
} finally {
cursor.close();
}
}
}
}

View File

@@ -32,6 +32,7 @@ import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.Settings;
@@ -751,4 +752,18 @@ public class ContactManager {
public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
}
/**
* Constants for a query to read basic contact columns
*/
final public static class ContactQuery {
private ContactQuery() {
}
public static final String[] PROJECTION =
new String[] {Contacts._ID, Contacts.DISPLAY_NAME};
public static final int COLUMN_ID = 0;
public static final int COLUMN_DISPLAY_NAME = 1;
}
}