package com.android.contacts;
import android.app.Activity;
+import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.Contacts;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.widget.Toast;
import java.io.ByteArrayOutputStream;
}
+ /**
+ * Is the raw_contact uri for the contact the user selected
+ */
Uri mContactUri;
@Override
mContactUri = icicle.getParcelable(CONTACT_URI_KEY);
} else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType(People.CONTENT_ITEM_TYPE);
+ intent.setType(Contacts.CONTENT_ITEM_TYPE);
startActivityForResult(intent, REQUEST_PICK_CONTACT);
}
}
}
if (requestCode == REQUEST_PICK_CONTACT) {
- mContactUri = result.getData();
// A contact was picked. Launch the cropper to get face detection, the right size, etc.
// TODO: get these values from constants somewhere
Intent myIntent = getIntent();
intent.putExtra("outputY", 96);
intent.putExtra("return-data", true);
startActivityForResult(intent, REQUEST_CROP_PHOTO);
+
+ // while they're cropping, convert the contact into a raw_contact
+ final long contactId = ContentUris.parseId(result.getData());
+ final long rawContactId = ContactsUtils.queryForRawContactId(getContentResolver(),
+ contactId);
+
+ if (rawContactId == -1) {
+ Toast.makeText(this, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
+ }
+
+ mContactUri = Uri.withAppendedPath(
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+ RawContacts.Data.CONTENT_DIRECTORY);
+
} else if (requestCode == REQUEST_CROP_PHOTO) {
final Bundle extras = result.getExtras();
if (extras != null) {
if (photo != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
- Contacts.People.setPhotoData(getContentResolver(), mContactUri,
- stream.toByteArray());
+
+ final ContentValues imageValues = new ContentValues();
+ imageValues.put(Photo.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+ imageValues.put(Photo.PHOTO, stream.toByteArray());
+ imageValues.put(RawContacts.Data.IS_SUPER_PRIMARY, 1);
+ getContentResolver().insert(mContactUri, imageValues);
}
}
finish();
private static final int QUERY_TOKEN = 42;
+ static final String KEY_PICKER_MODE = "picker_mode";
+
private ContactItemListAdapter mAdapter;
int mMode = MODE_DEFAULT;
switch (requestCode) {
case SUBACTIVITY_NEW_CONTACT:
if (resultCode == RESULT_OK) {
- // Contact was created, pass it back
returnPickerResult(null, data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME),
data.getData(), 0);
}
if (mMode == MODE_INSERT_OR_EDIT_CONTACT) {
Intent intent;
if (position == 0) {
- // Insert
intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
} else {
// Edit
intent = new Intent(Intent.ACTION_EDIT, uri);
}
intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
- final Bundle extras = getIntent().getExtras();
- if (extras != null) {
- intent.putExtras(extras);
+ Bundle extras = getIntent().getExtras();
+
+ if (extras == null) {
+ extras = new Bundle();
}
+ intent.putExtras(extras);
+ extras.putBoolean(KEY_PICKER_MODE, (mMode & MODE_MASK_PICKER) == MODE_MASK_PICKER);
+
startActivity(intent);
finish();
} else if (id != -1) {
}
} else if ((mMode & MODE_MASK_CREATE_NEW) == MODE_MASK_CREATE_NEW
&& position == 0) {
- // TODO: Hook this up to new edit contact activity (bug 2092559)
- /*Intent newContact = new Intent(Intents.Insert.ACTION, People.CONTENT_URI);
- startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);*/
+ Intent newContact = new Intent(Intents.Insert.ACTION, Contacts.CONTENT_URI);
+ startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);
} else {
signalError();
}
package com.android.contacts.ui;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.ScrollingTabWidget;
-import com.android.contacts.ViewContactActivity;
-import com.android.contacts.model.ContactsSource;
-import com.android.contacts.model.Editor;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.EntitySet;
-import com.android.contacts.model.HardCodedSources;
-import com.android.contacts.model.Sources;
-import com.android.contacts.model.Editor.EditorListener;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.ui.widget.ContactEditorView;
-import com.android.contacts.util.EmptyService;
-import com.android.contacts.util.WeakAsyncTask;
-import com.android.internal.widget.ContactHeaderWidget;
-import com.google.android.collect.Lists;
-
import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.widget.TextView;
import android.widget.Toast;
+import com.google.android.collect.Lists;
+
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.ScrollingTabWidget;
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.Editor;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.EntitySet;
+import com.android.contacts.model.HardCodedSources;
+import com.android.contacts.model.Sources;
+import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.ui.widget.ContactEditorView;
+import com.android.contacts.util.EmptyService;
+import com.android.contacts.util.WeakAsyncTask;
+import com.android.internal.widget.ContactHeaderWidget;
+
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
/**
* Activity for editing or inserting a contact.
return false;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
/**
* Background task for persisting edited contact data, using the changes
* defined by a set of {@link EntityDelta}. This task starts
private static final int RESULT_SUCCESS = 1;
private static final int RESULT_FAILURE = 2;
+ private long mSavedId;
+
+ private WeakReference<ProgressDialog> progress;
+
public PersistTask(EditContactActivity target) {
super(target);
}
/** {@inheritDoc} */
@Override
protected void onPreExecute(EditContactActivity target) {
+ this.progress = new WeakReference<ProgressDialog>(ProgressDialog.show(target, null,
+ target.getText(R.string.savingContact)));
+
// Before starting this task, start an empty service to protect our
// process from being reclaimed by the system.
final Context context = target;
try {
// Build operations and try applying
final ArrayList<ContentProviderOperation> diff = state.buildDiff();
- resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+ ContentProviderResult[] results;
+ if (!diff.isEmpty()) {
+ results = resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+ Intent intent = new Intent();
+ final long rawContactId = getRawContactId(state, diff, results);
+ final Uri rawContactUri = ContentUris.withAppendedId(
+ RawContacts.CONTENT_URI, rawContactId);
+
+ // convert the raw contact URI to a contact URI
+ final Uri contactLookupUri = RawContacts.getContactLookupUri(resolver,
+ rawContactUri);
+ intent.setData(contactLookupUri);
+ target.setResult(RESULT_OK, intent);
+ target.finish();
+ }
result = (diff.size() > 0) ? RESULT_SUCCESS : RESULT_UNCHANGED;
break;
return result;
}
+ private long getRawContactId(EntitySet state,
+ final ArrayList<ContentProviderOperation> diff,
+ final ContentProviderResult[] results) {
+ long rawContactId = state.findRawContactId();
+ if (rawContactId != -1) {
+ return rawContactId;
+ }
+
+ // we gotta do some searching for the id
+ final int diffSize = diff.size();
+ for (int i = 0; i < diffSize; i++) {
+ ContentProviderOperation operation = diff.get(i);
+ if (operation.getType() == ContentProviderOperation.TYPE_INSERT
+ && operation.getUri().getEncodedPath().contains(
+ RawContacts.CONTENT_URI.getEncodedPath())) {
+ return ContentUris.parseId(results[i].uri);
+ }
+ }
+ return -1;
+ }
+
/** {@inheritDoc} */
@Override
protected void onPostExecute(EditContactActivity target, Integer result) {
Toast.makeText(context, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
}
+ progress.get().dismiss();
+ target.finish();
// Stop the service that was protecting us
context.stopService(new Intent(context, EmptyService.class));
}
}
/**
- * Timeout for a {@link PersistTask} running on a background thread. This is
- * just shorter than the ANR timeout, so that we hold off user interaction
- * as long as possible.
- */
- private static final long TIMEOUT_PERSIST = 4000;
-
- /**
* Saves or creates the contact based on the mode, and if successful
* finishes the activity.
*/
private boolean doSaveAction() {
if (!hasValidState()) return false;
- // Pass back last-selected contact
- final Long rawContactId = this.getSelectedRawContactId();
- if (rawContactId != null) {
- final Intent intent = new Intent();
- intent.putExtra(ViewContactActivity.RAW_CONTACT_ID_EXTRA, (long)rawContactId);
- setResult(RESULT_OK, intent);
- }
-
- try {
- final PersistTask task = new PersistTask(this);
- task.execute(mState);
- task.get(TIMEOUT_PERSIST, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- // Ignore when someone cancels the operation
- } catch (TimeoutException e) {
- // Ignore when task is taking too long
- } catch (ExecutionException e) {
- // Important exceptions are handled on remote thread
- }
+ final PersistTask task = new PersistTask(this);
+ task.execute(mState);
- // Persisting finished, or we timed out waiting on it. Either way,
- // finish this activity, the background task will keep running.
- this.finish();
return true;
}