Save the date! Android Dev Summit is coming to Mountain View, CA on November 7-8, 2018.

Объекты Intent и фильтры объектов Intent

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

  • Для запуска операции:

    Компонент Activity представляет собой один экран в приложении. Для запуска нового экземпляра компонента Activity необходимо передать объект Intent методуstartActivity(). Объект Intent описывает операцию, которую требуется запустить, а также содержит все остальные необходимые данные.

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

  • Для запуска службы:

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

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

  • Для рассылки широковещательных сообщений:

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

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

Есть два типа объектов Intent:

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

Когда создан явный объект Intent для запуска операции или службы, система немедленно запускает компонент приложения, указанный в объекте Intent.

Рисунок 1. Схематическое изображение процесса передачи неявного объекта Intent по системе для запуска другой операции: [1] Операция А создает объект Intent с описанием действия и передает его методу startActivity(). [2] Система Android ищет во всех приложениях фильтры Intent, которые соответствуют данному объекту Intent. Когда приложение с подходящим фильтром найдено, [3] система запускает соответствующую операцию (Операция B), вызвав ее метод onCreate() и передав ему объект Intent.

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

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

Внимание! В целях обеспечения безопасности приложения всегда используйте явный объект Intent при запуске Service и не объявляйте фильтры Intent для своих служб. Запуск служб с помощью неявных объектов Intent является рискованным с точки зрения безопасности, поскольку нельзя быть на абсолютно уверенным, какая служба отреагирует на такой объект Intent, а пользователь не может видеть, какая служба запускается. Начиная с Android 5.0 (уровень API 21) система вызывает исключение при вызове метода bindService() с помощью неявного объекта Intent.

Создание объекта Intent

Объект Intent содержит информацию, на основании которой система Android определяет, какой компонент требуется запустить (например, точное имя компонента или категорию компонентов, которые должны получить этот объект Intent), а также сведения, которые необходимы компоненту-получателю, чтобы надлежащим образом выполнить действие (а именно — выполняемое действие и данные, с которыми его требуется выполнить).

Основные сведения, содержащиеся в объекте Intent:

Имя компонента
Имя компонента, который требуется запустить.

Эта информация является необязательной, но именно она и делает объект Intent явным. Ее наличие означает, что объект Intent следует доставить только компоненту приложения, определенному по имени. При отсутствии имени компонента объект Intent является неявным, а система определяет, какой компонент получит этот объект Intent по другим сведениям, которые в нем содержатся (например, по действию, данным и категории — см. описание далее). Поэтому, если вам требуется запустить определенный компонент из своего приложения, следует указать его имя.

Примечание. При запуске Service следует всегда указывать имя компонента. В противном случае вы не сможете быть на абсолютно уверенным в том, какая служба отреагирует на объект Intent, а пользователь не может видеть, какая служба запускается.

Это поле объекта Intent представляет собой объект ComponentName, который можно указать с помощью полного имени класса целевого компонента, включая имя пакета приложения. Например, com.example.ExampleActivity. Задать имя компонента можно с помощью метода setComponent(), setClass(), setClassName() или конструктора Intent.

Действие
Строка, определяющая стандартное действие, которое требуется выполнить (например, view (просмотр) или pick (выбор)).

При выдаче объектов Intent с широковещательными сообщениями это действие, которое произошло и о котором сообщается. Действие в значительной степени определяет, каким образом структурирована остальная часть объекта Intent,—в частности, что именно содержится в разделе данных и дополнительных данных.

Для использования объектами Intent в пределах своего приложения (либо для использования другими приложениями, чтобы вызывать компоненты из вашего приложения) можно указать собственные действия. Обычно же следует использовать константы действий, определенные классом Intent или другими классами платформы. Вот несколько стандартных действий для запуска операции:

ACTION_VIEW
Используйте это действие в объекте Intent с методом startActivity(), когда имеется определенная информация, которую операция может показать пользователю, например, фотография в приложении галереи или адрес для просмотра в картографическом приложении.
ACTION_SEND
Его еще называют объектом Intent "share" (намерение предоставить общий доступ). Это действие следует использовать в объекте Intent с методом startActivity(), при наличии определенных данных, доступ к которым пользователь может предоставить через другое приложение, например приложение для работы с электронной почтой или социальными сетями.

Другие константы, определяющие стандартные действия, см. в справочнике по классу Intent . Другие действия определяются в других частях платформы Android. Например, в Settings определяются действия, открывающие ряд экранов приложения настройки системы.

Действие можно указать для объекта Intent с методом setAction() или конструктором Intent.

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

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Данные
URI (объект Uri), ссылающийся на данные, с которыми будет выполняться действие и/или тип MIME этих данных. Тип передаваемых данных обычно определяется действием объекта Intent. Например, если действием является ACTION_EDIT, в данных должен содержаться URI документа, который требуется отредактировать.

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

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

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

Категория
Строка, содержащая прочие сведения о том, каким компонентом должна выполняться обработка этого объекта Intent. В объект Intent можно поместить любое количество описаний категорий, однако большинству объектов Intent категория не требуется. Вот некоторые стандартные категории:
CATEGORY_BROWSABLE
Целевая операция позволяет запускать себя веб-браузером для отображения данных, указанных по ссылке — например, изображения или сообщения электронной почты.
CATEGORY_LAUNCHER
Эта операция является начальной операцией задачи, она указана в средстве запуска приложений системы.

Полный список категорий см. в описании класса Intent .

Указать категорию можно с помощьюaddCategory().

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

Однако в объекте Intent может быть приведена и другая информация, которая не влияет на то, каким образом определяется требуемый компонент приложения. Объект Intent также может содержать:

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

Добавлять дополнительные данные можно с помощью различных методов putExtra(), каждый из которых принимает два параметра: имя и значение ключа. Также можно создать объект Bundle со всеми дополнительными данными, затем вставить объект Bundle в объект Intent с помощью метода putExtras().

Например, при создании объекта Intent для отправки сообщения электронной почты с методом ACTION_SEND можно указать получателя с помощью ключа EXTRA_EMAIL, а тему сообщения ― с помощью ключа EXTRA_SUBJECT.

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

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Флаги
Флаги, определенные в классе Intent, которые действуют как метаданные для объекта Intent. Флаги должны указывать системе Android, каким образом следует запускать операцию (например, к какой задаче должна принадлежать операция ) и как с ней обращаться после запуска (например, будет ли она указана в списке последних операций).

Подробные сведения см. в документе, посвященном методу setFlags().

Пример явного объекта Intent

Явные объекты Intent используются для запуска конкретных компонентов приложения, например определенной операции или службы. Чтобы создать явный объект Intent, задайте имя компонента для объекта Intent — все остальные свойства объекта Intent можно не задавать.

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

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

Конструктор Intent(Context, Class) предоставляет Context приложению, а компоненту ― объект Class. Фактически этот объект Intent явно запускает классDownloadService в приложении.

Подробные сведения о создании и запуске службы см. в руководстве Службы.

Пример неявного объекта Intent

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

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

Внимание! Возможна ситуация, когда на устройстве пользователя не будетникакого приложения, которое может откликнуться на неявный объект Intent, отправленный вами методу startActivity(). В этом случае вызов закончится неудачей, а работа приложения аварийно завершится. Чтобы проверить, будет получен ли операцией объект Intent, вызовите метод resolveActivity() для своего объекта Intent. Если результатом будет значение, отличное от null, значит, имеется хотя бы одно приложение, которое способно откликнуться на объект Intent и можно вызывать startActivity(). Если же результатом будет значение null, объект Intent не следует использовать и по возможности следует отключить функцию, которая выдает этот объект Intent.

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

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

При вызове метода startActivity() система анализирует все установленные приложения, чтобы определить, какие из них могут откликнуться на объект Intent этого вида (объект Intent с действием ACTION_SEND и данными "text/plain" ). Если имеется только одно подходящее приложение, оно будет сразу же открыто и получит данный объект Intent. Если объект Intent принимают несколько операций, система отображает диалоговое окно, в котором пользователь может выбрать приложение для выполнения данного действия.

Рисунок 2. Диалоговое окно выбора.

Принудительное использование блока выбора приложения

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

Однако если на объект Intent могут откликнуться несколько приложений, возможно, пользователь предпочтет каждый раз использовать другое приложение, поэтому следует явно выводить диалоговое окно выбора. В диалоговом окне выбора приложения пользователю предлагается при каждом запуске выбирать, какое приложение использовать для действия (пользователь не может выбрать приложение, используемое по умолчанию). Например, когда ваше приложение выполняет операцию "share" (поделиться) с помощью действия ACTION_SEND, пользователи могут, в зависимости от ситуации, предпочесть каждый раз делать это с помощью разных приложений , поэтому следует всегда использовать диалоговое окно выбора, как показано на рисунке 2.

Чтобы вывести на экран блок выбора приложения, создайте Intent с помощью createChooser() и передайте его startActivity(). Например:

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

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

Получение неявного объекта Intent

Чтобы указать, какие неявные объекты Intent может принимать ваше приложение, объявите один или несколько фильтров Intent для каждого компонента приложения с помощью элемента <intent-filter> в файле манифеста. Каждый фильтр Intent указывает тип объектов Intent, которые принимает компонент на основании действия, данных и категории, заданных в объекте Intent. Система передаст неявный объект Intent вашему приложению, только если он может пройти через один из ваших фильтров Intent.

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

Компонент приложения должен объявлять отдельные фильтры для каждой уникальной работы, которую он может выполнить. Например, у операции из приложения для работы с галереей изображений может быть два фильтра: один фильтр для просмотра изображения, и второй для его редактирования. Когда операция запускается, она анализирует объект Intent и выбирает режим своей работы на основании информации, приведенной в Intent (например, показывать элементы управления редактора или нет).

Каждый фильтр Intent определяется элементом <intent-filter> в файле манифеста приложения, указанном в объявлении соответствующего компонента приложения (например, в элементе <activity>). Внутри элемента <intent-filter>, можно указать тип объектов Intent, которые будут приниматься, с помощью одного или нескольких из следующих трех элементов:

<action>
Объявляет принимаемое действие, заданное в объекте Intent, в атрибуте name. Значение должно быть текстовой строкой действия, а не константой класса.
<data>
Объявляет тип принимаемых данных, для чего используется один или несколько атрибутов, указывающих различные составные части URI данных (scheme, host, port, path и т. д.) и тип MIME.
<category>
Объявляет принимаемую категорию, заданную в объекте Intent, в атрибуте name. Значение должно быть текстовой строкой действия, а не константой класса.

Примечание. Для получения неявных объектов Intent необходимо включить категорию CATEGORY_DEFAULT в фильтр Intent. Методы startActivity() и startActivityForResult() обрабатывают все объекты Intent, как если бы они объявляли категориюCATEGORY_DEFAULT. Если вы не объявляете эту категорию в своем фильтре Intent, никакие неявные объекты Intent не будут переданы в вашу операцию.

В следующем примере объявлена операция с фильтром Intent, определяющим получение объекта Intent ACTION_SEND, когда данные относятся к типу text:

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

Можно создавать фильтры, в которых будет несколько экземпляров &lt;action&gt;, &lt;data&gt; или &lt;category&gt;. В этом случае просто нужно убедиться в том, что компонент может справиться с любыми сочетаниями этих элементов фильтра.

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

Неявный объект Intent проверяется фильтром путем сравнения объекта Intent с каждым из этих трех элементов. Чтобы объект Intent был доставлен компоненту, он должен пройти все три теста. Если он не будет соответствовать хотя бы одному из них, система Android не доставит этот объект Intent компоненту. Однако, поскольку у компонента может быть несколько фильтров Intent, объект Intent, который не проходит через один из фильтров компонента, может пройти через другой фильтр. Подробные сведения о том, каким образом система принимает решения по поводу объектов Intent, см. в приведенном далее разделе Разрешение объектов Intent.

Внимание! Чтобы случайно не запустить Service другого приложения, всегда используйте явные объекты Intent для запуска собственных служб и не объявляйте для них фильтры Intent.

Примечание. Фильтры Intent необходимо объявлять в файле манифеста для всех операций. Фильтры для приемников широковещательных сообщений можно регистрировать динамически путем вызова registerReceiver(). После этого регистрацию приемника широковещательных сообщений можно отменить с помощью unregisterReceiver(). В результате ваше приложение сможет воспринимать определенные объявления только в течение указанного периода времени в процессе работы приложения.

Примеры фильтров

Чтобы лучше понять различные режимы работы фильтров 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) является основной точкой входа приложения — это операция, которая открывается, когда пользователь запускает приложение нажатием на его значок:

  • Действие ACTION_MAIN указывает на то, что это основная точка входа, и не ожидает никаких данных объекта Intent.
  • Категория CATEGORY_LAUNCHER указывает, что значок этой операции следует поместить в средство запуска приложений системы. Если элемент &lt;activity&gt; не содержит указаний на конкретный значок с помощью icon, то система воспользуется значком из элемента &lt;application&gt; .

Чтобы операция отображалась в средстве запуска приложений системы, два этих элемента необходимо связать вместе.

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

Примечание. Тип MIME (application/vnd.google.panorama360+jpg) является особым типом данных, указывающим на панорамные фотографии, с которыми можно работать с помощью API-интерфейсов Google panorama.

Использование ожидающего объекта Intent

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

Основные варианты использования ожидающего объекта Intent:

  • Объявление объекта Intent, который должен будет исполняться, когда пользователь выполняет действие с вашим уведомлением (NotificationManager системы Android исполняет Intent).
  • Объявление объекта Intent, который должен будет исполняться, когда пользователь выполняет действие с вашим виджетом приложения (приложение главного экрана исполняет Intent).
  • Объявление объекта Intent, который должен будет исполняться в указанное время в будущем (AlarmManager системы Android исполняет Intent).

Поскольку каждый объект Intent предназначен для обработки компонентом приложения, который относится к определенному типу (Activity, Service или BroadcastReceiver), объект PendingIntent также следует создавать с учетом этого обстоятельства. При использовании ожидающего объекта Intent ваше приложение не будет исполнять объект Intent вызовом, например, startActivity(). Вместо этого вам необходимо будет объявить требуемый тип компонента при создании PendingIntent путем вызова соответствующего метода-создателя:

Если только ваше приложение не принимает ожидающие объекты Intent от других приложений, указанные выше методы создания PendingIntent являются единственными методами PendingIntent, которые вам когда-либо понадобятся.

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

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

Разрешение объектов Intent

Когда система получает неявный объект Intent для запуска операции, она выполняет поиск наиболее подходящей операции путем сравнения объекта Intent с фильтрами Intent по трем критериям:

  • действие объекта Intent;
  • данные объекта Intent (тип URI и данных);
  • категория объекта Intent.

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

Тестирование действия

Для указания принимаемых действий объекта Intent фильтр Intent может объявлять любое (в том числе нулевое) число элементов action&gt;. Например:

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

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

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

Тестирование категории

Для указания принимаемых категорий объекта Intent фильтр Intent может объявлять любое (в том числе нулевое) число элементов &lt;category&gt;. Например:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

Чтобы объект Intent прошел тестирование категории, все категории, приведенные в объекте Intent, должны соответствовать категории из фильтра. Обратное не требуется — фильтр Intent может объявлять и другие категории, которых нет в объекте Intent, объект Intent при этом все равно пройдет тест. Поэтому объект Intent без категорий всегда пройдет этот тест, независимо от того, какие категории объявлены в фильтре.

Примечание. Система Android автоматически применяет категорию CATEGORY_DEFAULT ко всем неявным объектам Intent, которые передаются в startActivity() и startActivityForResult(). Поэтому, если вы хотите, чтобы ваша операция принимала неявные объекты Intent, в ее фильтрах Intent должна быть указана категория для "android.intent.category.DEFAULT" (как показано в предыдущем примере &lt;intent-filter&gt;).

Тестирование данных

Для указания принимаемых данных объекта Intent фильтр Intent может объявлять любое (в том числе нулевое) число элементов &lt;data&gt;. Например:

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

Каждый элемент <data> может конкретизировать структуру URI и тип данных (тип мультимедиа MIME). Имеются отдельные атрибуты — scheme, host, port и path — для каждой составной части URI:

&lt;scheme&gt;://&lt;host&gt;:&lt;port&gt;/&lt;path&gt;

Например:

content://com.example.project:200/folder/subfolder/etc

В этом URI схема имеет вид content, узел ― com.example.project, порт ― 200, а путь ― folder/subfolder/etc.

Каждый из этих атрибутов является необязательным в элементе &lt;data&gt;, однако имеются линейные зависимости:

  • Если схема не указана, узел игнорируется.
  • Если узел не указан, порт игнорируется.
  • Если не указана ни схема, ни узел, путь игнорируется.

Когда URI, указанный в объекте Intent, сравнивается с URI из фильтра, сравнение выполняется только с теми составными частями URI, которые приведены в фильтре. Например:

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

Примечание. Путь может быть указан с подстановочным символом (*), чтобы потребовалось только частичное соответствие имени пути.

При выполнении тестирования данных сравнивается и URI, и тип MIME, указанные в объекте Intent, с URI и типом MIME из фильтра. Действуют следующие правила:

  1. Объект Intent, который не содержит ни URI, ни тип MIME, пройдет этот тест, только если в фильтре не указано никаких URI или типов MIME.
  2. Объект Intent, в котором имеется URI, но отсутствует тип MIME (ни явный, ни тот, который можно вывести из URI), пройдет этот тест, только если URI соответствует формату URI из фильтра , а в фильтре также не указан тип MIME.
  3. Объект Intent, в котором имеется тип MIME, но отсутствует URI, пройдет этот тест, только если в фильтре указан тот же тип MIME и не указан формат URI.
  4. Объект Intent, в котором имеется и URI, и тип MIME (явный или тот, который можно вывести из URI), пройдет только часть этого теста, проверяющую тип MIME, в том случае, если этот тип совпадает с типом, приведенным в фильтре. Он пройдет часть этого теста, которая проверяет URI, либо если его URI совпадает с URI из фильтра, либо если этот объект содержит URI content: или file:, а в фильтре URI не указан. Другими словами, предполагается, что компонент поддерживает данные content: и file:, если в его фильтре указан только тип MIME.

Это последнее правило (правило (d)) отражает ожидание того, что компоненты будут в состоянии получать локальные данные из файла или от поставщика контента. Поэтому их фильтры могут содержать только тип данных, а явно указывать схемы content: и file: не требуется. Это типичный случай. Например, такой элемент &lt;data&gt;, как приведенный далее, сообщает системе Android, что компонент может получать данные изображений от поставщика контента и выводить их на экран:

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

Поскольку имеющиеся данные преимущественно распространяются поставщиками контента, фильтры, в которых указан тип данных и нет URI, вероятно, являются самыми распространенными.

Другой стандартной конфигурацией являются фильтры со схемой и типом данных. Например, такой элемент &lt;data&gt;, как приведенный далее, сообщает системе Android, что компонент может получать видеоданные из сети для выполнения действия:

<intent-filter>
    <data android:scheme="http" android:type="video/*" />
    ...
</intent-filter>

Сопоставление объектов Intent

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

Ваше приложение может использовать сопоставление объектов Intent таким же образом. В PackageManager имеется набор методов query...(), которые возвращают все компоненты, способные принять определенный объект, а также схожий набор методов resolve...(), которые определяют наиболее подходящий компонент, способный реагировать на объект Intent. Например, метод queryIntentActivities() возвращает передаваемый как аргумент список всех операций, которые могут выполнить объект Intent, а метод queryIntentServices() возвращает такой же список служб. Ни тот, ни другой метод не активирует компоненты; они просто перечисляют те из них, которые могут откликнуться. Имеется схожий метод для приемников широковещательных сообщений ( {@link android.content.pm.PackageManager#queryBroadcastReceivers ).