3. Использование неявных намерений. Фильтры намерений
Рассмотрим пример использования неявных намерений.
Пример работы неявного намерения
Представим, что мы хотим выслать некоторую информацию с помощью электронной почты. Создадим проект с одним Activity и кнопкой, по нажатию на которую должно открыться приложение для отправки электронной почты. Напишем обработчик нажатия на кнопку
Действие, которое мы хотим совершить, является обычной текстовой строкой. Набор стандартных действий содержится в классе Intent в виде набора статических констант. В этом же классе есть статические константы для указания дополнительных параметров действия. В нашем случае, это тема письма и содержимое сообщения. Метод setType()
устанавливает MIME-тип сообщения.
После указания параметров сообщения, мы вызываем метод startActivity()
, операционная система выбирает нужное Activity из списка всех Activity приложений, которые установлены на данном устройстве. Таким образом, с помощью неявного намерения мы можем открыть Activity другого приложения.
Запустим приложение в эмуляторе и нажмем на кнопку.
Как мы видим, операционная система показала диалоговое окно с предложением выбрать приложение, которое может обработать данное действие. Выбираем почтовый клиент Gmail (предварительно добавьте в приложение почтовый ящик) и видим, что тема и текст письма заполнены корректно.
Что будет, если никто не сможет обработать неявное намерение?
А что случится, если операционная система не найдет подходящее Activity, которое может обработать событие? Так как действие для обработки представляет собой обычную строку, мы можем указать произвольную строку в качестве действия.
Запустим приложение и нажмем на кнопку.
Как мы видим, было выброшено исключение и приложение закрылось с ошибкой. Если посмотреть логи устройства, можем обнаружить следующее сообщение
Операционная система не нашла подходящее Activity для обработки этого действия и выбросила исключение.
Чтобы обезопасить себя от подобных ситуаций, мы можем предварительно запросить у операционной системы список Activity, которое может обработать то или иное действие, и если список будет нулевой длины, мы можем не высылать неявное намерение, выдать пользователю сообщение о том, что невозможно выполнить действие или еще каким-либо образом обработать эту ситуацию и избежать закрытия приложения с ошибкой.
И теперь вместо закрытия приложения с ошибкой, пользователь видит следующее сообщение
Выбор обработчика намерения и самостоятельная обработка намерений
Давайте задумаемся, а как операционная система знает, какое Activity может обработать то или иное неявное намерение и можем ли мы создать Actvity, которое будет обрабатывать те или иные неявные намерения?
Мы интуитивно понимаем, что операционная система не обладает искусственным интеллектом и где-то должна быть указана информация о том, что то или иное Activity может обработать то или иное действие.
Данные об этом хранятся в манифесте приложения. При установке приложения, операционная система считывает файл манифеста и записывает информацию об Activity и о том, какие действия эта Activity может обработать.
В качестве примера создадим в тестовом приложении еще одно Activity и пропишем в файле манифеста следующую информацию
Как видите, мы используем элемент <intent-filter>, внутри которого прописываем action и некоторые дополнительные параметры действия (например, в данном случае мы можем обработать ACTION_SEND где тип сообщения text/plain).
В обработчике кнопки изменим действие на Intent.ACTION_SEND
и запустим эмулятор.
Как видим, в списке предложений, которые могут обработать действие Intent.ACTION_SEND
появилось наше приложение. Если мы выберем приложение, будет запущено SecondActivity.
Кстати обратите внимание на <intent-filter> для MainActivity
Значение ACTION_MAIN означает, что это Activity является входной точкой приложения - стартовым окном. Значение CATEGORY_LAUNCHER означает, что данное приложение должно отображаться в лаунчере устройства.
Таким образом, MainActivity является стартовым окном приложения. Если вы хотите изменить стартовое окно, просто переместите элемент <intent-filter> из элемента MainActivity в другое Activity.
Last updated