Adding an option to take a picture directly from Contacts app
Bug: 2480342
Change-Id: I4702e4177e524ff14962e81bd7749768920bd99a
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 26faaab..c861cb9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1106,4 +1106,9 @@
<!-- Button displayed underneath the list of filtered visible contacts -->
<string name="search_for_all_contacts">Search for all contacts</string>
+ <!-- An option in the 'change photo' or 'pick photo' dialog -->
+ <string name="take_photo">Take photo</string>
+
+ <!-- An option in the 'change photo' or 'pick photo' dialog -->
+ <string name="pick_photo">Select photo from Gallery</string>
</resources>
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 9ad0aa8..ba1f4fa 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -278,18 +278,6 @@
return true;
}
- public static Intent getPhotoPickIntent() {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
- intent.setType("image/*");
- intent.putExtra("crop", "true");
- intent.putExtra("aspectX", 1);
- intent.putExtra("aspectY", 1);
- intent.putExtra("outputX", 96);
- intent.putExtra("outputY", 96);
- intent.putExtra("return-data", true);
- return intent;
- }
-
public static long queryForContactId(ContentResolver cr, long rawContactId) {
Cursor contactIdCursor = null;
long contactId = -1;
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index 92fdadb..c33a329 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -58,8 +58,10 @@
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.RemoteException;
import android.provider.ContactsContract;
+import android.provider.MediaStore;
import android.provider.ContactsContract.AggregationExceptions;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.RawContacts;
@@ -81,6 +83,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
@@ -91,6 +95,7 @@
*/
public final class EditContactActivity extends Activity
implements View.OnClickListener, Comparator<EntityDelta> {
+
private static final String TAG = "EditContactActivity";
/** The launch code when picking a photo and the raw data is returned */
@@ -99,6 +104,9 @@
/** The launch code when a contact to join with is returned */
private static final int REQUEST_JOIN_CONTACT = 3022;
+ /** The launch code when taking a picture */
+ private static final int CAMERA_WITH_DATA = 3023;
+
private static final String KEY_EDIT_STATE = "state";
private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester";
private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator";
@@ -117,6 +125,10 @@
private static final int DIALOG_CONFIRM_MULTIPLE_DELETE = 3;
private static final int DIALOG_CONFIRM_READONLY_HIDE = 4;
+ private static final int ICON_SIZE = 96;
+
+ private static final String TEMP_FILENAME = "camera-t.jpg";
+
String mQuerySelection;
private long mContactIdForJoin;
@@ -541,6 +553,11 @@
break;
}
+ case CAMERA_WITH_DATA: {
+ doCropPhoto();
+ break;
+ }
+
case REQUEST_JOIN_CONTACT: {
if (resultCode == RESULT_OK && data != null) {
final long contactId = ContentUris.parseId(data.getData());
@@ -959,15 +976,135 @@
boolean doPickPhotoAction(long rawContactId) {
if (!hasValidState()) return false;
+ mRawContactIdRequestingPhoto = rawContactId;
+
+ showAndManageDialog(createPickPhotoDialog());
+
+ return true;
+ }
+
+ /**
+ * Creates a dialog offering two options: take a photo or pick a photo from the gallery.
+ */
+ private Dialog createPickPhotoDialog() {
+ Context context = EditContactActivity.this;
+
+ // Wrap our context to inflate list items using correct theme
+ final Context dialogContext = new ContextThemeWrapper(context,
+ android.R.style.Theme_Light);
+
+ String[] choices;
+ choices = new String[2];
+ choices[0] = getString(R.string.take_photo);
+ choices[1] = getString(R.string.pick_photo);
+ final ListAdapter adapter = new ArrayAdapter<String>(dialogContext,
+ android.R.layout.simple_list_item_1, choices);
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(dialogContext);
+ builder.setTitle(R.string.attachToContact);
+ builder.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ switch(which) {
+ case 0:
+ doTakePhoto();
+ break;
+ case 1:
+ doPickPhotoFromGallery();
+ break;
+ }
+ }
+ });
+ return builder.create();
+ }
+
+ /**
+ * Launches Camera to take a picture and store it in a temporary file.
+ */
+ protected void doTakePhoto() {
try {
- // Launch picker to choose photo for selected contact
- final Intent intent = ContactsUtils.getPhotoPickIntent();
- startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
- mRawContactIdRequestingPhoto = rawContactId;
+ // Launch camera to take photo for selected contact
+ final Intent intent = getTakePickIntent();
+ startActivityForResult(intent, CAMERA_WITH_DATA);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
}
- return true;
+ }
+
+ /**
+ * Constructs an intent for capturing a photo and storing it in a temporary file.
+ */
+ public static Intent getTakePickIntent() {
+ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
+ final File f = new File(Environment.getExternalStorageDirectory(), TEMP_FILENAME);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
+ return intent;
+ }
+
+ /**
+ * Sends a newly acquired photo to Gallery for cropping
+ */
+ protected void doCropPhoto() {
+ try {
+
+ // Add the image to the media store
+ final File f = new File(Environment.getExternalStorageDirectory(), TEMP_FILENAME);
+ final String photoUri = MediaStore.Images.Media.insertImage(getContentResolver(),
+ f.getAbsolutePath(), null, null);
+
+ // Delete the temporary file
+ f.delete();
+
+ // Launch gallery to crop the photo
+ final Intent intent = getCropImageIntent(Uri.parse(photoUri));
+ startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot crop image", e);
+ Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ /**
+ * Constructs an intent for image cropping.
+ */
+ public static Intent getCropImageIntent(Uri photoUri) {
+ Intent intent = new Intent("com.android.camera.action.CROP");
+ intent.setDataAndType(photoUri, "image/*");
+ intent.putExtra("crop", "true");
+ intent.putExtra("aspectX", 1);
+ intent.putExtra("aspectY", 1);
+ intent.putExtra("outputX", ICON_SIZE);
+ intent.putExtra("outputY", ICON_SIZE);
+ intent.putExtra("return-data", true);
+ return intent;
+ }
+
+ /**
+ * Launches Gallery to pick a photo.
+ */
+ protected void doPickPhotoFromGallery() {
+ try {
+ // Launch picker to choose photo for selected contact
+ final Intent intent = getPhotoPickIntent();
+ startActivityForResult(intent, PHOTO_PICKED_WITH_DATA);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(this, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ /**
+ * Constructs an intent for picking a photo from Gallery, cropping it and returning the bitmap.
+ */
+ public static Intent getPhotoPickIntent() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
+ intent.setType("image/*");
+ intent.putExtra("crop", "true");
+ intent.putExtra("aspectX", 1);
+ intent.putExtra("aspectY", 1);
+ intent.putExtra("outputX", ICON_SIZE);
+ intent.putExtra("outputY", ICON_SIZE);
+ intent.putExtra("return-data", true);
+ return intent;
}
/** {@inheritDoc} */