Фотосъемка

В уроке рассказывается как делать фотографии, используя существующие приложения.

Допустим вы разрабатываете приложение для службы погоды, которая строит глобальную карту погоды путем смешивания фотографий неба, сделанных с помощью встроенной камеры. Сама фотосъемка это лишь малая часть вашего приложения. Вы можете делать фотографии с минимальными усилиями, не изобретая велосипед. К счастью, большинство Android устройств включают в себя по крайней мере одно приложение для работы с камерой. В уроке мы покажем как их можно использовать для получения фото.

Получаем разрешение на камеру

Если получение снимков – важная часть вашего приложения, то показывайте его на Google Play только для устройств, которые имеют камеру. Для этого добавьте элемент <uses-features> в файл манифеста:

Если для большинства функций приложения камера не нужна, установите атрибут android:required в значение false. Тогда Google Play позволит устройствам без камеры загружать ваше приложение. В таком случае вы должны программно проверять наличие камеры с помощью метода hasSystemFeature(PackageManager.FEATURE_CAMERA). Если камера недоступна, отключите все функции, которые ее используют.

Получаем фото с помощью других приложений

Чтобы использовать другие приложение для каких-либо действий, в Android применяются намерения – объекты типа Intent, в которых описывается, что конкретно вы хотите сделать. Этот процесс включает три составляющих: само намерение – объект типа Intent, вызов внешнего явления – объекта типа Activity и некоторый код, который обрабатывает данные, полученные от внешнего явления.

Пример выполнения намерения для получения фотографии с камеры:

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

Получение миниатюр

Наверняка сам факт срабатывания затвора камеры это не предел желаний, и после съемки вы захотите получить картинку с камеры в ваше приложение, чтобы что-то с ней сделать.

Стандартное приложение “Камера” сжимает фото, которое возвращает намерение, в маленький объект типа Bitmap и передает в дополнительных данных с ключом "data". В следующем примере показано, как получить изображение и отобразить его в компоненте ImageView:

Примечание: миниатюра картинки из "data" хороша для иконки или аватара, но вряд ли хороша для чего-то большего. Получение полноразмерного изображения требует немного больше работы.

Сохранение полноразмерной фотографии

Приложение Камера сохраняет полноразмерное изображение, если передать ему имя файла для сохранения. Вы должны передать имя со всеми спецификаторами, чтобы приложение могло сохранить фотографию.

В целом, все сделанные с помощью камеры фотографии должны располагаться в публичной директории внешнего хранилища, чтобы любое приложение могло получить к ним доступ. Для получения общей директории для хранения фотографий служит метод getExternalStoragePublicDirectory(), в который нужно передать аргумент DIRECTORY_PICTURES. Поскольку метод возвращает каталог, доступный для всех приложений, необходимо получить разрешения READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE. Права на запись разрешают также чтение, поэтому если вы хотите записывать в публичный каталог и читать из него, добавьте только разрешение на запись:

Но если вы хотите получить фотографии, доступные только для вашего приложения, используйте директорию, которую возвращает метод getExternalFilesDir(). В Android 4.3 и ниже, запись в эту директорию также требует разрешения WRITE_EXTERNAL_STORAGE. Начиная с Android 4.4, права на запись не требуются, поскольку директория недоступна из других приложений. Добавляйте разрешение на запись в том случае, если поддерживаете приложения с ранними версиями, включив атрибут maxSdkVersion:

Примечание: файлы, сохраненные в директории, которую возвращает метод getExternalFilesDir(), удаляются вместе с приложением.

После выбора директории для файлов, необходимо выбрать устойчивое к коллизиям имя файла. Вы можете также сохранить директорию в переменной, чтобы использовать ее позже. Пример кода, который возвращает уникальное имя файла для новой фотографии, используя текущие дату и время:

Теперь, когда у нас есть метод для получения имени файла, можно создать и выполнить намерение:

Добавление фотографии в галерею

После создания фотографии с помощью намерения, вы знаете, где она находится, поскольку сообщили куда ее сохранить. Для всех остальных случаев, простейший способ получить доступ к созданной фотографии – использовать системный медиа-провайдер.

Примечание: если вы использовали директорию из метода getExternalFilesDir(), медиа-сканер не сможет получить доступ к этим файлам, поскольку они доступны только для вашего приложения.

Следующий пример показывает, как использовать системный медиа-сканер для того, чтобы добавить ваши фотографии в базу данных медиа-провайдера. После этого фотографии будут доступны в приложении Галерея, а также в других приложениях:

Масштабирование фотографий

Управление множеством полноразмерных фотографий требует хитрого подхода при ограниченной памяти. Если вы заметили, что приложение тратит всю доступную память уже после отображения нескольких фотографий, вы можете значительно уменьшить размер динамической памяти за счет расширения JPEG в массив памяти, который масштабируется в соответствии с размером компонента, в котором отображается картинка. Следующий пример демонстрирует данный подход:

Добавить комментарий