Android: получайте фотографии с камеры - будьте осторожны
В последнее время я написал приложение для Android, которое требовало сделать снимок со встроенной камеры и вернуть его обратно в мое приложение. Я использовал один из множества учебных пособий, и все работало нормально. Но затем я проверил это на другом устройстве, и ничего не работало вообще. Кажется, есть проблема, так как я могу сделать фото на каждом устройстве? (Смотрите мой ответ, это больше похоже на учебник)
1 ответ
Я использовал один из множества учебных пособий, и все работало нормально. Но затем я проверил это на другом устройстве, и ничего не работало вообще. Сначала я был очень удивлен, но затем я решил углубиться в эту тему. И я понял, что многие из этих уроков могут вызвать большие проблемы. Поэтому я решил поделиться с вами своим опытом.
Позвольте мне начать с общего подхода, который используется в большинстве учебных пособий.
Сначала вы выбираете requestID что-то вроде этого:
private static final int CAMERA_PIC_REQUEST = 1337;
Затем вы создаете намерение и запускаете камеру.
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
Чтобы вернуть изображение, вы используете функцию onActivityResult и считываете изображение из полученных данных о намерениях.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK && data != null) {
// do something like
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
}
}
Выглядит хорошо, не так ли? Ну, это работает, но теперь приходит сложная часть.
Как написано в документации для Android, данные о намерениях будут возвращать только саквояж или, скажем, уменьшенную версию снятой фотографии, а некоторые устройства вообще ничего не возвращают! Может даже случиться, что данные не равны NULL, но вы получите исключение "ResultInfo ResultInfo".
И что теперь? Решение для этого довольно просто. Вы просто указываете камере сохранить изображение на SD-карту и вернуть URI в этот файл. Ниже я покажу вам отредактированный код сверху.
Мы создаем статический requestID и URI
private static final int CAMERA_PIC_REQUEST = 1337;
private static Uri outputFileUri;
Мы затем создаем активность камеры, но на этот раз мы передаем дополнительный параметр (наш URI).
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
А теперь для обработки изображения мы используем тот же метод, что и выше, но вместо данных о намерениях мы используем наш URI
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
// do something to get the bitmap from the uri for example
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), outputFileUri);
}
С помощью этого решения вы можете быть уверены, что получите изображение на каждом устройстве. Но будьте осторожны, так как вы получаете полноразмерное растровое изображение, может потребоваться уменьшить растровое изображение, чтобы избежать ошибок нехватки памяти. Если вы не хотите сохранять изображение на SD-карте пользователя, просто удалите этот файл.
Спасибо за прочтение!