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:
@@ -47,7 +47,7 @@
|
|||||||
android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
|
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
android:label="@string/label">
|
android:label="@string/label">
|
||||||
@@ -112,6 +112,16 @@
|
|||||||
<data
|
<data
|
||||||
android:mimeType="vnd.android.cursor.item/raw_contact" />
|
android:mimeType="vnd.android.cursor.item/raw_contact" />
|
||||||
</intent-filter>
|
</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>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -102,4 +102,11 @@
|
|||||||
name="menu_done">Done</string>
|
name="menu_done">Done</string>
|
||||||
<string
|
<string
|
||||||
name="menu_cancel">Cancel</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>
|
</resources>
|
||||||
35
samples/SampleSyncAdapter/res/xml-v14/contacts.xml
Normal file
35
samples/SampleSyncAdapter/res/xml-v14/contacts.xml
Normal 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>
|
||||||
@@ -15,12 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.example.android.samplesync.editor;
|
package com.example.android.samplesync.editor;
|
||||||
|
|
||||||
|
import com.example.android.samplesync.Constants;
|
||||||
import com.example.android.samplesync.R;
|
import com.example.android.samplesync.R;
|
||||||
import com.example.android.samplesync.client.RawContact;
|
import com.example.android.samplesync.client.RawContact;
|
||||||
import com.example.android.samplesync.platform.BatchOperation;
|
import com.example.android.samplesync.platform.BatchOperation;
|
||||||
import com.example.android.samplesync.platform.ContactManager;
|
import com.example.android.samplesync.platform.ContactManager;
|
||||||
|
import com.example.android.samplesync.platform.ContactManager.ContactQuery;
|
||||||
import com.example.android.samplesync.platform.ContactManager.EditorQuery;
|
import com.example.android.samplesync.platform.ContactManager.EditorQuery;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
import android.accounts.AccountManager;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -29,6 +33,7 @@ import android.database.Cursor;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.ContactsContract;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||||
@@ -86,8 +91,8 @@ public class ContactEditorActivity extends Activity {
|
|||||||
mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
|
mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
|
||||||
mEmailEditText = (EditText)findViewById(R.id.editor_email);
|
mEmailEditText = (EditText)findViewById(R.id.editor_email);
|
||||||
|
|
||||||
// Figure out whether we're creating a new contact (ACTION_INSERT) or editing
|
// Figure out whether we're creating a new contact (ACTION_INSERT), editing
|
||||||
// an existing contact.
|
// an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (Intent.ACTION_INSERT.equals(action)) {
|
if (Intent.ACTION_INSERT.equals(action)) {
|
||||||
@@ -100,6 +105,24 @@ public class ContactEditorActivity extends Activity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
setAccountName(accountName);
|
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 {
|
} else {
|
||||||
// We're editing an existing contact. Load in the data from the contact
|
// We're editing an existing contact. Load in the data from the contact
|
||||||
// so that the user can edit it.
|
// so that the user can edit it.
|
||||||
@@ -163,7 +186,7 @@ public class ContactEditorActivity extends Activity {
|
|||||||
* successfully loaded from the Contacts data provider.
|
* successfully loaded from the Contacts data provider.
|
||||||
*/
|
*/
|
||||||
public void onRawContactEntityLoaded(Cursor cursor) {
|
public void onRawContactEntityLoaded(Cursor cursor) {
|
||||||
while (cursor.moveToNext()) {
|
if (cursor.moveToFirst()) {
|
||||||
String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
|
String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
|
||||||
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
|
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
|
||||||
setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
|
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
|
* Save the updated contact data. We actually take two different actions
|
||||||
* depending on whether we are creating a new contact or editing an
|
* 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) {
|
private void setAccountName(String accountName) {
|
||||||
mAccountName = accountName;
|
mAccountName = accountName;
|
||||||
|
Log.i(TAG, "account=" + mAccountName);
|
||||||
if (accountName != null) {
|
if (accountName != null) {
|
||||||
TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
|
TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
|
||||||
if (accountNameLabel != null) {
|
if (accountNameLabel != null) {
|
||||||
@@ -286,12 +327,11 @@ public class ContactEditorActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Cursor cursor) {
|
protected void onPostExecute(Cursor cursor) {
|
||||||
|
if (cursor == null) return;
|
||||||
// After we've successfully loaded the contact, call back into
|
// After we've successfully loaded the contact, call back into
|
||||||
// the ContactEditorActivity so we can update the UI
|
// the ContactEditorActivity so we can update the UI
|
||||||
try {
|
try {
|
||||||
if (cursor != null) {
|
onRawContactEntityLoaded(cursor);
|
||||||
onRawContactEntityLoaded(cursor);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
@@ -366,4 +406,25 @@ public class ContactEditorActivity extends Activity {
|
|||||||
onContactSaved(result);
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.provider.ContactsContract.CommonDataKinds.Im;
|
|||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||||
|
import android.provider.ContactsContract.Contacts;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
import android.provider.ContactsContract.Settings;
|
import android.provider.ContactsContract.Settings;
|
||||||
@@ -751,4 +752,18 @@ public class ContactManager {
|
|||||||
|
|
||||||
public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user