Афоризм
И жить не хочется, и застрелиться лень.
Наталья Резник
Последние статьи

 • Синхронизаторы потока
Примеры синхронизаторов пакета java.util.concurrent.
май 2019
 • Сервисы в Android
Неявное Intent отправки Email.
апрель 2019
 • Сервисы в Android
Описание и пример создания Android сервиса.
апрель 2019
 • Вызов AlarmClock
Неявное Intent для вызова AlarmClock.
март 2019
 • Намерения Intent
Описание Intent, фильтры объектов Intent.
март 2019
 • Пример 2-х Activity
Жизненные циклы 2-х Activity android положения.
март 2019
 • Описание Activity
Жизненный цикл Activity android положения.
февраль 2019
 • Отладка приложения
Logcat для просмотра сообщений, настройка BuildConfig.
февраль 2019
 • Настройка ListView
Настройка интерфейса прокручиваемого списка ListView.
февраль 2019
 • Фоновое изображение
Адаптация изображения при смене положения android.
январь 2019
 • Cписок ListView
Прокручиваемый список ListView в android.
январь 2019

Объект намерения Intent

При рассмотрении жизненных циклов двух активностей был использован объект Intent. С помощью данного объекта выполнялся переход из одной активности в другую и обратно. В данной статье рассматривается объект намерений Intent.

Intent представляет собой объект описания операции, которую необходимо выполнить через систему Android. Т.е. необходимо сначала описать некоторую операцию в виде объекта Intent, после чего отправить её на выполнение в систему вызовом одного из методов активности Activity.

Объекты Intent в основном используются в трёх операциях :

1. Старт операции
В android-приложении один экран представлен компонентом Activity, описанном в файле манифеста. Если необходимо в приложении иметь несколько экранов (страниц/форм), то все они должны быть зарегистрированы в манифесте приложения. Переход от одной активности к другой выполняется с помощью объекта Intent, который передается методу startActivity(). Объект Intent наряду с описанием операции может дополнительно включать все необходимые данные для выполнения операции.

Если необходимо получить результат выполнения операции, то следует использовать метод startActivityForResult(), который вернет отдельный объект Intent в обратном вызове метода onActivityResult().

2. Запуск сервиса
Android-приложение может выполнять действия в фоновом режиме без пользовательского интерфейса с помощью определенного сервиса, в качестве которого используется компонент Service. Сервис можно стартовать для выполнения какого-либо действия, например, чтение файла. Для старта сервиса необходимо вызвать метод активности startService() и передать ему объект Intent.

Если сервис имеет интерфейс типа клиент-сервер, то можно с ним установить связь через вызов метода bindService(), с передачей ему в качестве параметра объекта Intent.

3. Рассылка широковещательных сообщений
Широковещательное сообщение может принимать любое приложение android. Система генерирует различные широковещательные сообщения о системных событиях, например, зарядка устройства. Широковещательные сообщения отправляются другим приложениям передачей объекта Intent методам sendBroadcast(), sendOrderedBroadcast() или sendStickyBroadcast().

Типы объектов Intent

Существует два типа объектов Intent : явные и неявные.

Явные объекты Intent

Явные объекты Intent , как правило, используются для запуска компонента из собственного приложения, где известно наименование запускаемых классов и сервисов. В примере рассмотрения жизненных циклов двух активностей был использован следующий вызов 2-ой активности :

Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

В качестве первого параметра конструктора Intent указывается Context. Поскольку активность является наследником Context, то можно использовать укороченную запись this или полную как Class_name.this. Во втором параметре конструктора указывается наименование класса активности. Этот класс зарегистрирован в манифесте приложения. Таким образом, приложение может иметь несколько активностей, каждую из которых можно вызвать по наименованию класса. После вызова метода startActivity будет создана новая активность, которая запустится или возобновит свою работу, переместившись на вершину стека активностей.

Пример старта сервиса

Если в приложении был создан какой-либо сервис, например ServiceDownload для загрузки файлов из Интернета, то для запуска этого сервиса можно использовать следующий код :

// url определяет некоторый файл в интернете

String url = "http://www.example.com/image.png";
. . .
Intent intentDownload;
intentDownload = new Intent(this, ServiceDownload.class);
intentDownload.setData(Uri.parse(url));
startService(intentDownload);

Неявные объекты Intent

Неявные объекты Intent не содержат имени конкретного класса. Вместо этого они включают действие (action), которое требуется выполнить. Неявный Intent может включать дополнительно наименование категории (category) и тип данных (data). Такой набор параметров позволяют компоненту из другого приложения обработать этот запрос. Например, если необходимо пользователю показать место на карте, то с помощью неявного объекта Intent можно попросить это сделать другое приложение, в котором данная функция предусмотрена.

Когда android получает неявный объект Intent для выполнения, то система ищет подходящие компоненты путем сравнения содержимого Intent с фильтрами Intent других приложений, зарегистрированных в файлах манифестов. Если параметры объекта Intent совпадают с параметрами одного из фильтров Intent, то система запускает этот компонент и передает ему объект Intent. При наличии нескольких подходящих фильтров система открывает диалоговое окно, где пользователь может выбрать подходящее приложение.

Фильтр Intent представляет собой секцию в файле манифеста приложения, описывающее типы объектов Intent, которые компонент мог бы выполнить. Таким образом, наличие фильтра Intent в описании активности в манифесте позволяет другим приложениям напрямую запускать данную операцию с помощью некоторого объекта Intent. Если фильтр Intent не описан, то операцию можно будет запустить только с помощью явного объекта Intent.

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

В случае, если система не сможет выполнить неявное намерение при вызове метода startActivity или startActivityForResult, то приложение завершится с ошибкой. Чтобы не допустить этого следует использовать метод намерения resolveActivity для проверки возможности выполнения заданного действия. Пример использования метода resolveActivity рассмотрен на странице описания взаимодействия с AlarmClock.

Фильтры намерений Intent

В секциях фильтров намерений в файле манифеста можно объявить только три составляющих объекта Intent : действие, данные, категория. Рассмотрим пример описания фильтров намерений для приложения работы с социальными сетями.

<activity android:name="MainActivity">
    <!-- This activity is the main entry, 
            should appear in app launcher -->
    <intent-filter>
        <action   android:name=
                       "android.intent.action.MAIN" />
        <category android:name=
                      "android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions 
         with text data -->
    <intent-filter>
        <action   android:name="android.intent.action.SEND"/>
        <category android:name=
                          "android.intent.category.DEFAULT"/>
        <data     android:mimeType="text/plain"/>
    </intent-filter>

    <!-- This activity also handles "SEND" and 
         "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name=
                    "android.intent.action.SEND_MULTIPLE"/>
        <category android:name=
                    "android.intent.category.DEFAULT"/>
        <data android:mimeType=
                   "application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

Первая активность (MainActivity), открывающаяся при старте приложения, является главной точкой входа. Действие «android.intent.action.MAIN» говорит о том, что это основная точка входа в приложение и не требуется ожидания никаких объектов Intent. Категория «android.intent.category.LAUNCHER» указывает на то, что значок данной активности следует поместить в средство запуска приложений системы. Если элемент <activity> не содержит указаний на конкретный значок с помощью тега icon, то система воспользуется значком из элемента манифеста <application>.

Вторая активность (ShareActivity) предназначена для упрощения обмена текстовым и мультимедийным контентом. Несмотря на то, что пользователи могут входить в эту активность из MainActivity, они также могут открыть ShareActivity напрямую из другого приложения, которое создаст неявный объект Intent, соответствующий одному из двух фильтров Intent.

Действие намерения, action

Действие action объекта Intent определяет, что нужно выполнить, например просмотр фото (view) или выбор фото (pick). В значительной степени действие определяет, каким образом описана остальная часть намерения Intent, в частности, что именно содержится в разделе данных. Действие для объекта Intent можно указать методом setAction() или определить в конструкторе Intent. Если Вы определяете собственные действия, то необходимо использовать наименование пакета приложения. Например :

static final String ACTION_TRAVEL = "com.actions.TRAVEL";

Рассмотрим простой пример формирования неявного намерения для открытия определенной страницы сайта :

String url = "http://java-online.ru/android.xhtml";
Uri address = Uri.parse(url);
Intent urlIntent = new Intent(Intent.ACTION_VIEW, address);

if (urlIntent.resolveActivity(getPackageManager())!=null)
    startActivity(urlIntent);
else
    Log.d("Intent", "Intent (ACTION_VIEW) не обработан!");

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

ACTION_ANSWER Открывает активность, связанную с входящими звонками.
ACTION_CALL Открывает активность, инициализирующую обращение к телефону.
ACTION_HEADSET_PLUG Подключение наушников.
ACTION_SEND Вызов активности для отправки данных, указанных в намерении. Получатель должен быть определен с помощью полученной активности. Для указания типа передаваемых данных MIME используйте метод setType. Данные передаются параметром намерения extras с ключами EXTRA_TEXT или EXTRA_STREAM в зависимости от типа. При использовании электронной почты стандартное приложение принимает дополнительные параметры по ключам EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC и EXTRA_SUBJECT.
Действие ACTION_SEND следует использовать только в тех случаях, когда данные необходимо передать удаленному адресату, а не другой программе на том же устройстве.
ACTION_SENDTO Открывает активность для отправки сообщений контакту, указанному в пути URI, который определяется в намерении.
ACTION_VIEW Наиболее распространенное общее действие просмотра чего-либо. Выбор приложения зависит от схемы (протокола) данных : стандартные адреса http будут открывать браузер, адреса tel вызовут приложение для дозвона, geo откроет программу Google Maps, а данные с контактами откроют приложении для управления контактной информацией.
ACTION_WEB_SEARCH Открывает активность поиска информации в интернете, основываясь на передаваемых данных с помощью пути URI; как правило, при этом запускается браузер.

Действие, определяемое в манифесте, включает наименование пакета и не используют префикс "ACTION_", например, «android.intent.action.SEND». С другими константными действиями можно познакомиться в справочнике Intent.

Категория намерения, category

Категория – это строка, содержащая дополнительные сведения о том, каким компонентом должна выполняться обработка объекта Intent. В объект Intent можно поместить любое количество категорий. Однако большинству объектов Intent описание категории не требуется.

Класс Intent для работы с категориями имеет группу методов :

  • addCategory() — добавить категорию в объект Intent;
  • removeCategory() — удалить ранее добавленную категорию из объекта Intent;
  • getCategories() — получить набор категорий объекта Intent.

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

BROWSABLE Операция стартует веб-браузер для отображения данных, указанных по ссылке (url), например, изображение или сообщение электронной почты.
LAUNCHER Операция (активность) является начальной операцией задачи. Активность с данной категорией помещается в окно для запуска приложений.
DEFAULT Данная категория позволяет объявить компонент обработчиком по умолчанию для действия, выполняемого с указанным типом данных внутри фильтра намерений.
HOME Активность с данной категорией отображает главный экран (Home Screen), который открывается после включения устройства и загрузки системы, или когда нажимается клавиша HOME.

Константные наименования категории, используемые в java-коде, имеют префикс "CATEGORY_". С другими константными категориями можно познакомиться в справочнике Intent.

Данные намерения

При создании объекта Intent в некоторых случая необходимо определить данные (data). Например, для действия ACTION_EDIT, данные должны включать URI документа, который требуется отредактировать. Объект Uri ссылается на данные и/или тип этих данных MIME. Так, например, операция, которая выводит на экран изображения, скорее всего, не сможет воспроизвести аудио/видео файл, даже если и у тех, и у других данных будут одинаковые форматы URI. Поэтому указание типа данных MIME помогает системе Android найти наиболее подходящий компонент для выполнения объекта Intent.

Чтобы задать только URI данных, используйте метод setData(). Чтобы определить только тип MIME, вызовите setType(). При необходимости определения обоих параметров можно вызвать метод setDataAndType().

Примечание : чтобы определить URI и тип MIME следует использовать метод setDataAndType(). Не вызывайте методы setData() и setType() поочередно, поскольку каждый из этих методов аннулирует результат выполнения другого.

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

  • android:host – определение имени удалённого сервера, например, google.com;
  • android:port – определение порта удалённого сервера;
  • android:path – определение пути URI;
  • android:mimetype – определение типа данных, которые компонент может обрабатывать;
  • android:scheme – необходимо использовать конкретную схему (например, content или http).

В файле манифеста наряду с фильтрами намерений Intent настраиваются и другие параметры приложения. О том, как настроить атрибут configChanges, чтобы приложение реагировало на изменение ориентации устройста (portrait|landscape) или на изменение размера экрана можно прочитать здесь.

Дополнительные данные

Данные, содержащие дополнительную информацию, необходимую для выполнения запрошенного действия, определяются в виде пары "ключ-значение". Добавлять дополнительные данные можно с помощью различных методов putExtra(), каждый из которых принимает два параметра : имя и значение ключа. Также можно создать объект Bundle с дополнительными данными и вставить его в Intent с помощью метода putExtras(). Например, для отправки сообщения электронной почты адрес получателя можно указать с помощью ключа EXTRA_EMAIL, а тему сообщения ― с помощью ключа EXTRA_SUBJECT.

Класс Intent имеет несколько констант EXTRA_* для стандартных типов данных. Если необходимо использовать собственные дополнительные ключи для объектов Intent, которые принимает только ваше приложение, обязательно указывайте в качестве префикса имя пакета своего приложения. Например :

static final String EXTRA_WATT = "com.example.EXTRA_WATT";

Определение намерения, запустившего активность

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

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
	
    Intent intent = getIntent();
}

Методы getAction() и getData() позволяют определить действие и данные, связанные с намерением. Для получения дополнительной информации, хранящейся в параметре extras, используйте типизированные методы get<Type>Extra.

String action = intent.getAction();
Uri    data   = intent.getData();

Связанные страницы

Intent взаимодействия с AlarmClock
Intent отправки Email
Жизненные циклы двух Activity
Фоновое изображение в Layout

  Рейтинг@Mail.ru