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.
This commit is contained in:
Dorian Scholz 2014-03-03 04:30:50 +01:00
parent 33000582ed
commit a183f8d387
2 changed files with 33 additions and 42 deletions

View File

@ -9,7 +9,6 @@ import android.graphics.BitmapFactory;
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.MediaStore;
import android.text.Editable; import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; 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.Directory;
import org.whispersystems.textsecure.directory.NotInDirectoryException; import org.whispersystems.textsecure.directory.NotInDirectoryException;
import org.whispersystems.textsecure.util.InvalidNumberException; import org.whispersystems.textsecure.util.InvalidNumberException;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -80,8 +79,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
private final DynamicTheme dynamicTheme = new DynamicTheme(); private final DynamicTheme dynamicTheme = new DynamicTheme();
private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
private File pendingFile = null;
private static final int PICK_CONTACT = 1; private static final int PICK_CONTACT = 1;
private static final int PICK_AVATAR = 2; private static final int PICK_AVATAR = 2;
public static final int AVATAR_SIZE = 210; public static final int AVATAR_SIZE = 210;
@ -260,13 +257,6 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
public void onClick(View view) { public void onClick(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT, null); Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT, null);
photoPickerIntent.setType("image/*"); 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); 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); ((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 @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
MenuInflater inflater = this.getSupportMenuInflater(); MenuInflater inflater = this.getSupportMenuInflater();
@ -392,8 +364,9 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
} }
syncAdapterWithSelectedContacts(); syncAdapterWithSelectedContacts();
break; break;
case PICK_AVATAR: case PICK_AVATAR:
new DecodeCropAndSetAsyncTask().execute(); new DecodeCropAndSetAsyncTask(data.getData()).execute();
break; break;
} }
} }
@ -496,13 +469,23 @@ public class GroupCreateActivity extends PassphraseRequiredSherlockFragmentActiv
} }
private class DecodeCropAndSetAsyncTask extends AsyncTask<Void,Void,Bitmap> { private class DecodeCropAndSetAsyncTask extends AsyncTask<Void,Void,Bitmap> {
private final Uri avatarUri;
DecodeCropAndSetAsyncTask(Uri uri) {
avatarUri = uri;
}
@Override @Override
protected Bitmap doInBackground(Void... voids) { protected Bitmap doInBackground(Void... voids) {
if (pendingFile != null) { if (avatarUri != null) {
avatarBmp = BitmapUtil.getCircleCroppedBitmap(BitmapFactory.decodeFile(pendingFile.getAbsolutePath())); InputStream inputStream;
pendingFile.delete(); try {
pendingFile = null; inputStream = getApplicationContext().getContentResolver().openInputStream(avatarUri);
} catch (FileNotFoundException e) {
Log.w(TAG, e);
return null;
}
avatarBmp = BitmapUtil.getScaledCircleCroppedBitmap(BitmapFactory.decodeStream(inputStream), AVATAR_SIZE);
} }
return avatarBmp; return avatarBmp;
} }

View File

@ -106,21 +106,29 @@ public class BitmapUtil {
public static Bitmap getCircleCroppedBitmap(Bitmap bitmap) { public static Bitmap getCircleCroppedBitmap(Bitmap bitmap) {
if (bitmap == null) return null; if (bitmap == null) return null;
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), final int srcSize = Math.min(bitmap.getWidth(), bitmap.getHeight());
bitmap.getHeight(), Bitmap.Config.ARGB_8888); 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); 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 int color = 0xff424242;
final Paint paint = new Paint(); final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
paint.setAntiAlias(true); paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0); canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color); paint.setColor(color);
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, canvas.drawCircle(destSize / 2, destSize / 2, destSize / 2, paint);
bitmap.getWidth() / 2, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint); canvas.drawBitmap(bitmap, srcRect, destRect, paint);
return output; return output;
} }