From a183f8d3879897b5f3af074dafbd11d9be017870 Mon Sep 17 00:00:00 2001 From: Dorian Scholz Date: Mon, 3 Mar 2014 04:30:50 +0100 Subject: [PATCH] Fix #641 by using standard intent to select group avatar. The ACTION_GET_CONTENT used with cropping is not supported on all devices. To make this work more reliably I removed the cropping and MediaStore.EXTRA_OUTPUT. The image is now read via getContentResolver().openInputStream() which should work on all device including KitKat/CM11. --- .../securesms/GroupCreateActivity.java | 55 +++++++------------ .../securesms/util/BitmapUtil.java | 20 +++++-- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/src/org/thoughtcrime/securesms/GroupCreateActivity.java b/src/org/thoughtcrime/securesms/GroupCreateActivity.java index 8ae7f7078f..f83750854f 100644 --- a/src/org/thoughtcrime/securesms/GroupCreateActivity.java +++ b/src/org/thoughtcrime/securesms/GroupCreateActivity.java @@ -9,7 +9,6 @@ import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.provider.MediaStore; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -51,10 +50,10 @@ import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.directory.Directory; import org.whispersystems.textsecure.directory.NotInDirectoryException; import org.whispersystems.textsecure.util.InvalidNumberException; -import org.whispersystems.textsecure.util.PhoneNumberFormatter; import java.io.ByteArrayOutputStream; -import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -80,8 +79,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv private final DynamicTheme dynamicTheme = new DynamicTheme(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); - private File pendingFile = null; - private static final int PICK_CONTACT = 1; private static final int PICK_AVATAR = 2; public static final int AVATAR_SIZE = 210; @@ -260,13 +257,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv public void onClick(View view) { Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT, null); photoPickerIntent.setType("image/*"); - photoPickerIntent.putExtra("crop", "true"); - photoPickerIntent.putExtra("aspectX", 1); - photoPickerIntent.putExtra("aspectY", 1); - photoPickerIntent.putExtra("outputX", AVATAR_SIZE); - photoPickerIntent.putExtra("outputY", AVATAR_SIZE); - photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getAvatarTempUri()); - photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString()); startActivityForResult(photoPickerIntent, PICK_AVATAR); } }); @@ -274,24 +264,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv ((RecipientsEditor)findViewById(R.id.recipients_text)).setHint(R.string.recipients_panel__add_member); } - private Uri getAvatarTempUri() { - return Uri.fromFile(createAvatarTempFile()); - } - - private File createAvatarTempFile() { - try { - File f = File.createTempFile("avatar", ".tmp", getFilesDir()); - pendingFile = f; - f.setWritable(true, false); - f.deleteOnExit(); - return f; - } catch (IOException ioe) { - Log.e(TAG, "Error creating new temp file.", ioe); - Toast.makeText(getApplicationContext(), R.string.GroupCreateActivity_file_io_exception, Toast.LENGTH_SHORT).show(); - return null; - } - } - @Override public boolean onPrepareOptionsMenu(Menu menu) { MenuInflater inflater = this.getSupportMenuInflater(); @@ -392,9 +364,10 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv } syncAdapterWithSelectedContacts(); break; + case PICK_AVATAR: - new DecodeCropAndSetAsyncTask().execute(); - break; + new DecodeCropAndSetAsyncTask(data.getData()).execute(); + break; } } @@ -496,13 +469,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv } private class DecodeCropAndSetAsyncTask extends AsyncTask { + private final Uri avatarUri; + + DecodeCropAndSetAsyncTask(Uri uri) { + avatarUri = uri; + } @Override protected Bitmap doInBackground(Void... voids) { - if (pendingFile != null) { - avatarBmp = BitmapUtil.getCircleCroppedBitmap(BitmapFactory.decodeFile(pendingFile.getAbsolutePath())); - pendingFile.delete(); - pendingFile = null; + if (avatarUri != null) { + InputStream inputStream; + try { + inputStream = getApplicationContext().getContentResolver().openInputStream(avatarUri); + } catch (FileNotFoundException e) { + Log.w(TAG, e); + return null; + } + avatarBmp = BitmapUtil.getScaledCircleCroppedBitmap(BitmapFactory.decodeStream(inputStream), AVATAR_SIZE); } return avatarBmp; } diff --git a/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/src/org/thoughtcrime/securesms/util/BitmapUtil.java index 3c76ffb85c..c192784673 100644 --- a/src/org/thoughtcrime/securesms/util/BitmapUtil.java +++ b/src/org/thoughtcrime/securesms/util/BitmapUtil.java @@ -106,21 +106,29 @@ public class BitmapUtil { public static Bitmap getCircleCroppedBitmap(Bitmap bitmap) { if (bitmap == null) return null; - Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), - bitmap.getHeight(), Bitmap.Config.ARGB_8888); + final int srcSize = Math.min(bitmap.getWidth(), bitmap.getHeight()); + return getScaledCircleCroppedBitmap(bitmap, srcSize); + } + + public static Bitmap getScaledCircleCroppedBitmap(Bitmap bitmap, int destSize) { + if (bitmap == null) return null; + Bitmap output = Bitmap.createBitmap(destSize, destSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); + final int srcSize = Math.min(bitmap.getWidth(), bitmap.getHeight()); + final int srcX = (bitmap.getWidth() - srcSize) / 2; + final int srcY = (bitmap.getHeight() - srcSize) / 2; + final Rect srcRect = new Rect(srcX, srcY, srcX + srcSize, srcY + srcSize); + final Rect destRect = new Rect(0, 0, destSize, destSize); final int color = 0xff424242; final Paint paint = new Paint(); - final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); - canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, - bitmap.getWidth() / 2, paint); + canvas.drawCircle(destSize / 2, destSize / 2, destSize / 2, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - canvas.drawBitmap(bitmap, rect, rect, paint); + canvas.drawBitmap(bitmap, srcRect, destRect, paint); return output; }