Краткое введение в предварительно созданные контракты API ActivityResult

Получение изображения с помощью пользовательского ввода - обычная задача в разработке под Android. Однако реализовать его далеко не так просто. На ранних этапах разработки под Android, чтобы позволить пользователю сделать снимок и предварительно просмотреть его, потребовалось немало усилий. То же самое касается выбора изображения через приложение галереи.

Но со временем Google предоставляет все больше и больше API, которые упрощают эти задачи и, следовательно, нашу повседневную жизнь как разработчиков. В настоящее время у нас есть доступ к ActivityResult API, который позволяет нам использовать ActivityResultContract API.

На более ранних этапах, если мы хотели получить результат от Intent, нам нужно было переопределить onActivityResult()функцию, установить коды запроса и так далее.

Благодаря API ActivityResult мы теперь можем упростить этот процесс, сэкономить много кода и получить более четкий способ получения данных с помощью ActivityResultContract.

В этой статье мы хотим сосредоточиться на следующих двух контрактах:

ActivityResultContracts.TakePicture()
ActivityResultContracts.GetContent()

Как следует из названия, TakePicture() принимает в качестве параметра Uri файла. Затем он автоматически открывает собственное приложение камеры, заботится об обработке разрешений и обо всем остальном, о чем нам раньше приходилось заботиться сами.

GetContent(), с другой стороны, предлагает пользователю выбрать фрагмент контента. В нашем случае мы хотим, чтобы пользователь выбрал изображение из своей галереи. Чтобы указать, какой тип mime следует выбрать, мы можем добавить фильтр типа, например. «image / *» при запуске контракта.

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

Реализация

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

1 Настройте проект

Мы начинаем реализацию с настройки нашего проекта с шаблоном EmptyActivity. Откройте файл app-levelbuild.gradle и убедитесь, что включены следующие зависимости:

2 Создание макета

После этого замените макет действия следующим кодом:

Как видите, у нас есть MaterialCardView для предварительного просмотра изображения. За включенные кнопки отвечают либо TakePicture(), либо GetContent()..

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



3 Адаптация упражнения

API ActivityResult работает с так называемыми «контрактами». Как вы реализуете индивидуальные контракты - это тема для отдельной статьи.

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

Затем создайте новую папку XML в каталоге значений и добавьте файл с именем provider_paths.xml..

Добавив их, приложение теперь может взаимодействовать с файловой системой. Теперь мы готовы к собственно логике. Адаптируйте код вашего MainActivity к следующему:

Как видите, реализация довольно проста. Мы определяем контракты как их собственные переменные. Очевидно, takeImageResult означает получение изображения через приложение камеры. selectImageFromGallerResult для поиска изображений через приложение галереи соответственно.

3.1 Сделать снимок - приложение камеры

takeImageResult запускается предоставлением файла Uri. Поэтому, прежде чем мы сможем запустить этот контракт, мы создаем временный файл с функцией getTmpFileUri() и получаем соответствующий Uri с помощью FileProvider.

Чтобы позже получить доступ к Uri, мы сохраняем его в переменной latestTmpUri. При запуске takeImageResult и получении изображения с помощью приложения камеры мы получаем логическую isSuccess переменную, которая сообщает нам, был ли захват фотографии успешным.

Если процесс завершился успешно, мы получаем доступ к Uri через latestTmpUri и устанавливаем его на предварительный просмотр ImageView, который содержится в MaterialCardView.

3.2 Выберите изображение - приложение "Галерея"

Для сравнения, выбор изображения через приложение-галерею проще. Мы запускаем selectImageFromGallerResult контракт, просто указав тип контента, который мы хотим получить. Поскольку мы хотим получить изображение, мы устанавливаем его на "image/*".

В результате мы получаем соответствующий Uri, который затем можем установить для нашего предварительного просмотра ImageView.

4 Результат

Если вы успешно выполнили предыдущие шаги, результат должен выглядеть следующим образом на примере получения изображения.

Заключение

В этой статье я показал вам, как использовать уже встроенные контракты ActivityResult API, предлагаемые Google, чтобы быстро и легко получать изображения из галереи изображений или с помощью приложения «Камера».

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

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

Это не только потому, что у нас меньше кода, но и потому, что нам больше не нужно обрабатывать несколько кодов результатов и проверять, для чего был вызван onActivityResult()method.

Подводя итог, я могу только посоветовать вам попробовать API. Мне любопытно, будет ли Google предлагать больше встроенных контрактов в будущем.

Надеюсь, у вас есть какие-то выводы, аплодируйте, если вам понравилась моя статья, и следите за новостями!