1ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani/* 2ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Copyright (C) 2013 The Android Open Source Project 3ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * 4ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 5ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * you may not use this file except in compliance with the License. 6ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * You may obtain a copy of the License at 7ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * 8ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 9ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * 10ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * Unless required by applicable law or agreed to in writing, software 11ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 12ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * See the License for the specific language governing permissions and 14ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani * limitations under the License. 15ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani */ 16ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 17ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasanipackage com.android.settings.users; 18ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 19ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.app.Activity; 20ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.app.Fragment; 21ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.ClipData; 22ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.Context; 23ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.Intent; 24ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.content.pm.PackageManager; 25ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.database.Cursor; 26ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Bitmap; 27ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.BitmapFactory; 28ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Canvas; 29ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Paint; 30ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Rect; 31ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.Bitmap.Config; 32ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.graphics.drawable.Drawable; 33ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.net.Uri; 34ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.os.AsyncTask; 35ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.provider.MediaStore; 36ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.provider.ContactsContract.DisplayPhoto; 37ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.support.v4.content.FileProvider; 382a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglioimport android.util.Log; 39ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.view.View; 40ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.view.View.OnClickListener; 41ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.AdapterView; 42ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ArrayAdapter; 43ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ImageView; 44ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ListAdapter; 45ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport android.widget.ListPopupWindow; 46ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 47ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport com.android.settings.R; 48fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghinaimport com.android.settings.drawable.CircleFramedDrawable; 49ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 50ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.File; 51ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.FileNotFoundException; 522a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglioimport java.io.IOException; 53ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.io.InputStream; 54ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.util.ArrayList; 55ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasaniimport java.util.List; 56ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 57ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasanipublic class EditUserPhotoController { 582a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio private static final String TAG = "EditUserPhotoController"; 592a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio 60ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final int POPUP_LIST_ITEM_ID_CHOOSE_PHOTO = 1; 61ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final int POPUP_LIST_ITEM_ID_TAKE_PHOTO = 2; 62ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 63ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani // It seems that this class generates custom request codes and they may 64ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani // collide with ours, these values are very unlikely to have a conflict. 65ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final int REQUEST_CODE_CHOOSE_PHOTO = 1001; 66ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final int REQUEST_CODE_TAKE_PHOTO = 1002; 67ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final int REQUEST_CODE_CROP_PHOTO = 1003; 68ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 69ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final String CROP_PICTURE_FILE_NAME = "CropEditUserPhoto.jpg"; 70ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto2.jpg"; 71ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 72ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final int mPhotoSize; 73ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 74ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final Context mContext; 75ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final Fragment mFragment; 76ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final ImageView mImageView; 77ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 78ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final Uri mCropPictureUri; 79ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private final Uri mTakePictureUri; 80ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 81ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private Bitmap mNewUserPhotoBitmap; 82ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private Drawable mNewUserPhotoDrawable; 83ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 84ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public EditUserPhotoController(Fragment fragment, ImageView view, 85ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Bitmap bitmap, Drawable drawable, boolean waiting) { 86ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mContext = view.getContext(); 87ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mFragment = fragment; 88ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mImageView = view; 89ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mCropPictureUri = createTempImageUri(mContext, CROP_PICTURE_FILE_NAME, !waiting); 90ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mTakePictureUri = createTempImageUri(mContext, TAKE_PICTURE_FILE_NAME, !waiting); 91ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mPhotoSize = getPhotoSize(mContext); 92ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mImageView.setOnClickListener(new OnClickListener() { 93ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani @Override 94ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public void onClick(View v) { 95ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani showUpdatePhotoPopup(); 96ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 97ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani }); 98ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mNewUserPhotoBitmap = bitmap; 99ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mNewUserPhotoDrawable = drawable; 100ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 101ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 102ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public boolean onActivityResult(int requestCode, int resultCode, Intent data) { 103ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (resultCode != Activity.RESULT_OK) { 104ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return false; 105ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 106ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final Uri pictureUri = data != null && data.getData() != null 107ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani ? data.getData() : mTakePictureUri; 108ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani switch (requestCode) { 109ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani case REQUEST_CODE_CROP_PHOTO: 110ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani onPhotoCropped(pictureUri, true); 111ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return true; 112ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani case REQUEST_CODE_TAKE_PHOTO: 113ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani case REQUEST_CODE_CHOOSE_PHOTO: 114ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani cropPhoto(pictureUri); 115ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return true; 116ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 117ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return false; 118ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 119ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 120ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public Bitmap getNewUserPhotoBitmap() { 121ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return mNewUserPhotoBitmap; 122ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 123ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 124ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public Drawable getNewUserPhotoDrawable() { 125ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return mNewUserPhotoDrawable; 126ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 127ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 128ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void showUpdatePhotoPopup() { 129ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final boolean canTakePhoto = canTakePhoto(); 130ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final boolean canChoosePhoto = canChoosePhoto(); 131ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 132ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (!canTakePhoto && !canChoosePhoto) { 133ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return; 134ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 135ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 136ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Context context = mImageView.getContext(); 137ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final List<EditUserPhotoController.AdapterItem> items = new ArrayList<EditUserPhotoController.AdapterItem>(); 138ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 139ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (canTakePhoto()) { 140ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani String title = mImageView.getContext().getString( R.string.user_image_take_photo); 141ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_TAKE_PHOTO); 142ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani items.add(item); 143ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 144ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 145ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (canChoosePhoto) { 146ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani String title = context.getString(R.string.user_image_choose_photo); 147ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani EditUserPhotoController.AdapterItem item = new AdapterItem(title, POPUP_LIST_ITEM_ID_CHOOSE_PHOTO); 148ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani items.add(item); 149ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 150ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 151ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final ListPopupWindow listPopupWindow = new ListPopupWindow(context); 152ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 153ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setAnchorView(mImageView); 154ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setModal(true); 155ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 156ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 157ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani ListAdapter adapter = new ArrayAdapter<EditUserPhotoController.AdapterItem>(context, 158ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani R.layout.edit_user_photo_popup_item, items); 159ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setAdapter(adapter); 160ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 161ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final int width = Math.max(mImageView.getWidth(), context.getResources() 162ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani .getDimensionPixelSize(R.dimen.update_user_photo_popup_min_width)); 163ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setWidth(width); 164ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 165ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() { 166ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani @Override 167ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 168ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani EditUserPhotoController.AdapterItem item = items.get(position); 169ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani switch (item.id) { 170ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani case POPUP_LIST_ITEM_ID_CHOOSE_PHOTO: { 171ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani choosePhoto(); 172ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.dismiss(); 173ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } break; 174ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani case POPUP_LIST_ITEM_ID_TAKE_PHOTO: { 175ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani takePhoto(); 176ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.dismiss(); 177ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } break; 178ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 179ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 180ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani }); 181ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 182ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani listPopupWindow.show(); 183ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 184ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 185ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private boolean canTakePhoto() { 186ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return mImageView.getContext().getPackageManager().queryIntentActivities( 187ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani new Intent(MediaStore.ACTION_IMAGE_CAPTURE), 188ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani PackageManager.MATCH_DEFAULT_ONLY).size() > 0; 189ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 190ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 191ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private boolean canChoosePhoto() { 192ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 193ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.setType("image/*"); 194ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return mImageView.getContext().getPackageManager().queryIntentActivities( 195ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent, 0).size() > 0; 196ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 197ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 198ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void takePhoto() { 199ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 200ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani appendOutputExtra(intent, mTakePictureUri); 201ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mFragment.startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO); 202ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 203ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 204ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void choosePhoto() { 205ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 206ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.setType("image/*"); 207ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani appendOutputExtra(intent, mTakePictureUri); 208ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mFragment.startActivityForResult(intent, REQUEST_CODE_CHOOSE_PHOTO); 209ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 210ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 211ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void cropPhoto(Uri pictureUri) { 212ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani // TODO: Use a public intent, when there is one. 213ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Intent intent = new Intent("com.android.camera.action.CROP"); 214ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.setDataAndType(pictureUri, "image/*"); 215ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani appendOutputExtra(intent, mCropPictureUri); 216ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani appendCropExtras(intent); 217ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (intent.resolveActivity(mContext.getPackageManager()) != null) { 218ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mFragment.startActivityForResult(intent, REQUEST_CODE_CROP_PHOTO); 219ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } else { 220ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani onPhotoCropped(pictureUri, false); 221ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 222ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 223ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 224ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void appendOutputExtra(Intent intent, Uri pictureUri) { 225ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri); 226ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION 227ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani | Intent.FLAG_GRANT_READ_URI_PERMISSION); 228ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, pictureUri)); 229ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 230ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 231ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void appendCropExtras(Intent intent) { 232ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("crop", "true"); 233ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("scale", true); 234ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("scaleUpIfNeeded", true); 235ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("aspectX", 1); 236ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("aspectY", 1); 237ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("outputX", mPhotoSize); 238ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani intent.putExtra("outputY", mPhotoSize); 239ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 240ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 241ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private void onPhotoCropped(final Uri data, final boolean cropped) { 242ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani new AsyncTask<Void, Void, Bitmap>() { 243ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani @Override 244ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani protected Bitmap doInBackground(Void... params) { 245ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (cropped) { 2462a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio InputStream imageStream = null; 247ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani try { 2482a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio imageStream = mContext.getContentResolver() 249ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani .openInputStream(data); 250ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return BitmapFactory.decodeStream(imageStream); 251ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } catch (FileNotFoundException fe) { 2522a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio Log.w(TAG, "Cannot find image file", fe); 253ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return null; 2542a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio } finally { 2552a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio if (imageStream != null) { 2562a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio try { 2572a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio imageStream.close(); 2582a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio } catch (IOException ioe) { 2592a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio Log.w(TAG, "Cannot close image stream", ioe); 2602a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio } 2612a8f7cb7367577d6a1e3b1406117a93c76e525a1Fabrice Di Meglio } 262ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 263ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } else { 264ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani // Scale and crop to a square aspect ratio 265ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Bitmap croppedImage = Bitmap.createBitmap(mPhotoSize, mPhotoSize, 266ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Config.ARGB_8888); 267ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Canvas canvas = new Canvas(croppedImage); 268ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Bitmap fullImage = null; 269ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani try { 270ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani InputStream imageStream = mContext.getContentResolver() 271ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani .openInputStream(data); 272ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani fullImage = BitmapFactory.decodeStream(imageStream); 273ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } catch (FileNotFoundException fe) { 274ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return null; 275ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 276ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (fullImage != null) { 277ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final int squareSize = Math.min(fullImage.getWidth(), 278ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani fullImage.getHeight()); 279ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final int left = (fullImage.getWidth() - squareSize) / 2; 280ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final int top = (fullImage.getHeight() - squareSize) / 2; 281ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Rect rectSource = new Rect(left, top, 282ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani left + squareSize, top + squareSize); 283ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Rect rectDest = new Rect(0, 0, mPhotoSize, mPhotoSize); 284ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Paint paint = new Paint(); 285ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani canvas.drawBitmap(fullImage, rectSource, rectDest, paint); 286ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return croppedImage; 287ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } else { 288ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani // Bah! Got nothin. 289ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return null; 290ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 291ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 292ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 293ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 294ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani @Override 295ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani protected void onPostExecute(Bitmap bitmap) { 296ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (bitmap != null) { 297ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mNewUserPhotoBitmap = bitmap; 298ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mNewUserPhotoDrawable = CircleFramedDrawable 299ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani .getInstance(mImageView.getContext(), mNewUserPhotoBitmap); 300ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani mImageView.setImageDrawable(mNewUserPhotoDrawable); 301ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 302ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani new File(mContext.getCacheDir(), TAKE_PICTURE_FILE_NAME).delete(); 303ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani new File(mContext.getCacheDir(), CROP_PICTURE_FILE_NAME).delete(); 304ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 305ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 306ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 307ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 308ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static int getPhotoSize(Context context) { 309ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani Cursor cursor = context.getContentResolver().query( 310ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, 311ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani new String[]{DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null); 312ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani try { 313ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani cursor.moveToFirst(); 314ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return cursor.getInt(0); 315ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } finally { 316ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani cursor.close(); 317ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 318ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 319ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 320ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private Uri createTempImageUri(Context context, String fileName, boolean purge) { 321ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final File folder = context.getCacheDir(); 322ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani folder.mkdirs(); 323ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final File fullPath = new File(folder, fileName); 324ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani if (purge) { 325ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani fullPath.delete(); 326ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 327ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final Uri fileUri = 328ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani FileProvider.getUriForFile(context, RestrictedProfileSettings.FILE_PROVIDER_AUTHORITY, fullPath); 329ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return fileUri; 330ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 331ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 332ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani private static final class AdapterItem { 333ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final String title; 334ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani final int id; 335ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 336ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public AdapterItem(String title, int id) { 337ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani this.title = title; 338ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani this.id = id; 339ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 340ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani 341ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani @Override 342ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani public String toString() { 343ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani return title; 344ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 345ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani } 346ee3987475e1d29e8355bdb9e068149eb01e3fd43Amith Yamasani}