Если ваше приложение может выполнять действие, которое может быть полезно для другого приложения, подготовьте его к реагированию на запросы действий, указав соответствующий фильтр интентов в своей активности.
Например, если вы создаете социальное приложение, в котором можно делиться сообщениями или фотографиями с друзьями, поддерживайте намерение ACTION_SEND.
Когда пользователь нажмет кнопку "Поделиться" в другом приложении, ваше приложение появится в
списке доступных вариантов (см. рисунок 1).
Рисунок 1. Диалоговое окно выбора.
Чтобы разрешить другим приложениям вызывать ваш объект activity, добавьте элемент <intent-filter> в файл манифеста для соответствующего элемента <activity>.
Когда приложение устанавливается на устройство, система определяет фильтры интентов и добавляет информацию о них во внутренний каталог интентов, поддерживаемых всеми установленными приложениями.
Когда приложение вызывает startActivity() или startActivityForResult() с неявным намерением, система проверяет, какие действия могут на него ответить.
Добавьте фильтр интентов
Чтобы правильно определить, какие интенты может обрабатывать ваша Activity, сделайте каждый добавляемый фильтр интентов как можно более конкретным с точки зрения типа действия и данных, которые принимает Activity.
Система может отправить определенный объект Intent в объект activity, если у него есть фильтр интентов, соответствующий следующим критериям объекта Intent:
- Действие
- Строка, указывающая на действие, которое нужно выполнить. Обычно это одно из значений, определенных платформой, например
ACTION_SENDилиACTION_VIEW.Укажите это в фильтре интентов с помощью элемента
<action>. В этом элементе необходимо указать полное название действия, а не константу API, как показано в примерах на этой странице. - Данные
- Описание данных, связанных с намерением.
Укажите это в фильтре интентов с помощью элемента
<data>. С помощью одного или нескольких атрибутов в этом элементе можно указать MIME-тип, префикс URI, схему URI или их комбинацию, чтобы обозначить тип принимаемых данных.Примечание. Если вам не нужно указывать конкретные сведения о данных,
Uriнапример когда ваше действие обрабатывает другие виды дополнительных данных, вместо URI укажите только атрибутandroid:mimeType, чтобы объявить тип данных, которые обрабатывает ваше действие, напримерtext/plainилиimage/jpeg. - Категория
- Дополнительный способ описать действие, обрабатывающее намерение. Обычно он связан с жестом пользователя или местоположением, из которого оно запущено. Система поддерживает несколько разных категорий, но большинство из них используется редко. Однако все неявные намерения по умолчанию определяются с помощью
CATEGORY_DEFAULT.Укажите это в фильтре интентов с помощью элемента
<category>.
В фильтре интентов можно указать, какие критерии принимает действие, объявив каждый из них с помощью соответствующих XML-элементов, вложенных в элемент <intent-filter>.
Например, ниже показано действие с фильтром интентов, который обрабатывает интент ACTION_SEND, когда тип данных – текст или изображение.
<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"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
Совет. Если вы хотите, чтобы значок в диалоговом окне выбора отличался от значка действия по умолчанию, добавьте android:icon в элемент <intent-filter>.
Каждый входящий интент указывает только одно действие и один тип данных, но в каждом элементе <intent-filter> можно объявить несколько экземпляров элементов <action>, <category> и <data>.
Если какие-либо две пары действия и данных являются взаимоисключающими в своем поведении, создайте отдельные фильтры интентов, чтобы указать, какие действия допустимы в паре с какими типами данных.
Например, предположим, что ваше действие обрабатывает и текст, и изображения для намерений ACTION_SEND и ACTION_SENDTO. В этом случае необходимо определить два отдельных фильтра интентов для двух действий, поскольку интент ACTION_SENDTO должен использовать данные Uri, чтобы указать адрес получателя с помощью схемы URI send или sendto. Это показано в следующем примере:
<activity android:name="ShareActivity"> <!-- Filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- Filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
Примечание. Чтобы получать неявные интенты, необходимо включить категорию CATEGORY_DEFAULT в фильтр интентов. Методы startActivity() и startActivityForResult() обрабатывают все намерения так, как если бы они объявляли категорию CATEGORY_DEFAULT. Если вы не объявите его в фильтре интентов, неявные интенты не будут разрешаться в вашу Activity.
Подробнее о том, как отправлять и получать объекты ACTION_SEND Intent, которые выполняют действия по публикации в социальных сетях, рассказывается в статье Получение простых данных от других приложений.
Полезную информацию об обмене данными можно найти в статьях Обмен простыми данными и Обмен файлами.
Обработка намерения в действии
Чтобы решить, какое действие выполнить в активности, прочитайте Intent, которое используется для ее запуска.
При запуске действия вызовите getIntent(), чтобы получить Intent, запустивший действие. Это можно сделать в любой момент жизненного цикла действия, но обычно это делается во время ранних обратных вызовов, таких как onCreate() или onStart().
Это показано в следующем примере:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) val data: Uri? = intent?.data // Figure out what to do based on the intent type if (intent?.type?.startsWith("image/") == true) { // Handle intents with image data } else if (intent?.type == "text/plain") { // Handle intents with text } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data } else if (intent.getType().equals("text/plain")) { // Handle intents with text } }
Возврат результата
Если вы хотите вернуть результат в действие, которое вызвало ваше, вызовите setResult(), чтобы указать код результата и результат Intent. Когда операция будет завершена и пользователь вернется к исходному действию, вызовите finish(), чтобы закрыть и удалить действие. Это показано в следующем примере:
Kotlin
// Create intent to deliver some kind of result data Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result -> setResult(Activity.RESULT_OK, result) } finish()
Java
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")); setResult(Activity.RESULT_OK, result); finish();
Вместе с результатом всегда нужно указывать код результата. Обычно это RESULT_OK или RESULT_CANCELED. При необходимости вы можете добавить дополнительные данные с помощью Intent.
Примечание. По умолчанию в качестве результата задано значение RESULT_CANCELED. Если пользователь нажмет кнопку "Назад", не выполнив действие и не задав результат, исходное действие получит результат "Отменено".
Если вам нужно просто вернуть целое число, указывающее на один из нескольких вариантов результата, вы можете задать для кода результата любое значение больше 0. Если вы используете код результата, чтобы передать целое число, и вам не нужно включать Intent, вы можете вызвать setResult() и передать только код результата:
Kotlin
setResult(RESULT_COLOR_RED) finish()
Java
setResult(RESULT_COLOR_RED); finish();
В этом случае возможных результатов может быть немного, поэтому код результата – это локально определенное целое число (больше 0). Это хорошо работает, когда вы возвращаете результат в операцию в своем приложении, поскольку операция, получающая результат, может ссылаться на общедоступную константу для определения значения кода результата.
Примечание. Вам не нужно проверять, было ли действие запущено с помощью startActivity() или startActivityForResult(). Просто вызовите setResult(), если намерение, запустившее действие, может ожидать результат. Если исходное действие вызвало startActivityForResult(), система передает ему результат, который вы передаете в setResult(). В противном случае результат игнорируется.