Единственное намерение позволить пользователю сделать снимок ИЛИ выбрать изображение из галереи на Android

Я разрабатываю приложение для Android 2.1 вверх. Я хочу, чтобы мои пользователи могли выбрать изображение профиля в моем приложении (я не использую структуру контактов).

Идеальным решением было бы запустить намерение, позволяющее пользователю выбирать изображение из галереи, но если подходящее изображение недоступно, используйте камеру для съемки (или наоборот, то есть разрешите пользователю делать снимок, но если Они уже знают, что у них уже есть подходящее изображение, пусть они попадают в галерею и выбирают изображение).

В настоящее время я могу сделать то или другое, но не то, и другое.

Если я перейду непосредственно в режим камеры с помощью MediaStore.ACTION_IMAGE_CAPTURE, тогда нет возможности попасть в галерею.

Если я перейду непосредственно в галерею с помощью Intent.ACTION_PICK, тогда я смогу выбрать изображение, но если я нажму кнопку камеры (в правом верхнем углу галереи), то будет запущено новое намерение камеры. Таким образом, любая сделанная фотография не возвращается непосредственно в мое приложение. (Конечно, вы можете нажать кнопку «Назад», чтобы вернуться в галерею и выбрать изображение, но это лишний ненужный шаг и вовсе не интуитивно понятен).

Итак, есть ли способ объединить оба, или я собираюсь предложить меню, чтобы сделать то или другое из моего приложения? Похоже, это будет обычный случай использования … неужели я что-то упустил?

Solutions Collecting From Web of "Единственное намерение позволить пользователю сделать снимок ИЛИ выбрать изображение из галереи на Android"

ОБНОВЛЕНИЕ : другой ответ, использующий EXTRA_INITIAL_INTENTS , является лучшим на данный момент. В то время, когда я написал свой ответ, EXTRA_INITIAL_INTENTS еще не существовал, поскольку он был добавлен в API Level 5.

Итак, есть ли способ объединить оба, или я собираюсь предложить меню, чтобы сделать то или другое из моего приложения?

Напишите свою собственную галерею, в которой есть функции, которые вы хотите.

Я бы подумал, что меню будет проще.

Похоже, это будет обычный случай использования … неужели я что-то упустил?

Разработчик рядом с вами подумает, что галерея должна позволить вам выбрать из местной галереи или же перепрыгнуть на Flickr, чтобы сделать выбор оттуда. Другой разработчик подумает, что камера должна не только «делать снимок» через камеру, но и «делать снимок», выбирая что-то из галереи, переворачивая вещи так, как вы ее себе представляете. Еще один разработчик подумает, что галерея должна позволять выбирать из местной галереи, или Flickr, или камеры, или веб-камеры, привязанной к сети. Еще один разработчик подумает, что галерея глупа, и пользователи должны просто выбирать файлы через проводник файлов. И так далее.

Все это в среде (мобильных телефонах), где флэш-память для ОС стоит больших денег.

Следовательно, IMHO, не совсем шокирует то, что основная команда Android решила предоставить вам строительные блоки, которые вы сочтете подходящими, вместо того, чтобы пытаться приспособить все возможные шаблоны.

Вы можете попробовать сделать что-то вроде этого:

 // ... // Within your enclosing Class // ... private static final int SELECT_PICTURE = 1; // ... Intent pickIntent = new Intent(); pickIntent.setType("image/*"); pickIntent.setAction(Intent.ACTION_GET_CONTENT); Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String pickTitle = "Select or take a new Picture"; // Or get from strings.xml Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle); chooserIntent.putExtra ( Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent } ); startActivityForResult(chooserIntent, SELECT_PICTURE); 

Чтобы узнать, как обрабатывать результат деятельности, обратитесь к этому вопросу.


Примечание: критическая точка заключается в том, как определить, использовалась ли камера или галерея. Это показано в этом примере кода: https://stackoverflow.com/a/12347567/294884

Вы можете действовать следующим образом:

 private static final int REQUEST_CODE_PICTURE= 1; /** * Click on View to change photo. Sets into View of your layout, android:onClick="clickOnPhoto" * @param view View */ public void clickOnPhoto(View view) { Intent pickIntent = new Intent(); pickIntent.setType("image/*"); pickIntent.setAction(Intent.ACTION_GET_CONTENT); Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String pickTitle = "Take or select a photo"; Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent }); startActivityForResult(chooserIntent, REQUEST_CODE_PICTURE); } 

Затем добавьте всегда в свою активность метод onActivityResult:

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) { if (data == null) { return; } try { InputStream inputStream = getContentResolver().openInputStream(data.getData()); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); imgPhoto.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } }