Общие намерения

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

Когда вы вызываете startActivity() или startActivityForResult() и передаёте ему неявное намерение, система определяет приложение, которое может его обработать, и запускает соответствующую Activity . Если существует несколько приложений, способных обработать намерение, система предлагает пользователю диалоговое окно для выбора нужного приложения.

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

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

Если вы не знакомы с тем, как создавать намерения или фильтры намерений, сначала прочтите раздел Намерения и фильтры намерений .

Чтобы узнать, как активировать намерения, перечисленные на этой странице, с вашего хоста разработки, см. раздел Проверка намерений с помощью Android Debug Bridge .

Голосовые действия Google

Голосовые команды Google активируют некоторые из намерений, перечисленных на этой странице, в ответ на голосовые команды. Подробнее см. в разделе «Начало работы с системными голосовыми командами» .

Будильник

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

Создать будильник

Голосовые действия Google

  • "поставь будильник на 7 утра"

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

Примечание: В Android 2.3 (API уровня 9) и ниже доступны только дополнительные функции часов, минут и сообщений. Остальные дополнительные функции доступны в более поздних версиях платформы.

Действие
ACTION_SET_ALARM
URI данных
Никто
Тип MIME
Никто
Дополнительно
EXTRA_HOUR
Час будильника.
EXTRA_MINUTES
Минуты будильника.
EXTRA_MESSAGE
Пользовательское сообщение для идентификации тревоги.
EXTRA_DAYS
ArrayList включающий все дни недели, в которые повторяется этот будильник. Каждый день должен быть объявлен целым числом из класса Calendar , например, MONDAY .

Для одноразового будильника не указывайте эту дополнительную опцию.

EXTRA_RINGTONE
content: URI, указывающий рингтон, который будет использоваться с будильником, или VALUE_RINGTONE_SILENT для отсутствия рингтона.

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

EXTRA_VIBRATE
Логическое значение, указывающее, следует ли вибрировать при срабатывании этого будильника.
EXTRA_SKIP_UI
Логическое значение, указывающее, должно ли отвечающее приложение пропускать свой пользовательский интерфейс при установке будильника. Если значение равно true, приложение должно пропустить любой пользовательский интерфейс подтверждения и установить указанный будильник.

Пример намерения:

Котлин

fun createAlarm(message: String, hour: Int, minutes: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_HOUR, hour)
        putExtra(AlarmClock.EXTRA_MINUTES, minutes)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
Примечание:

Чтобы вызвать намерение ACTION_SET_ALARM , ваше приложение должно иметь разрешение SET_ALARM :

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Создать таймер

Голосовые действия Google

  • "установить таймер на 5 минут"

Чтобы создать таймер обратного отсчета, используйте действие ACTION_SET_TIMER и укажите данные таймера, например длительность, с помощью следующих дополнительных параметров.

Примечание: это намерение доступно в Android 4.4 (уровень API 19) и выше.

Действие
ACTION_SET_TIMER
URI данных
Никто
Тип MIME
Никто
Дополнительно
EXTRA_LENGTH
Длительность таймера в секундах.
EXTRA_MESSAGE
Пользовательское сообщение для идентификации таймера.
EXTRA_SKIP_UI
Логическое значение, указывающее, должно ли отвечающее приложение пропускать свой пользовательский интерфейс при установке таймера. Если значение равно true, приложение должно пропустить любой пользовательский интерфейс подтверждения и запустить указанный таймер.

Пример намерения:

Котлин

fun startTimer(message: String, seconds: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
Примечание:

Чтобы вызвать намерение ACTION_SET_TIMER , ваше приложение должно иметь разрешение SET_ALARM :

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Показать все будильники

Чтобы отобразить список будильников, используйте действие ACTION_SHOW_ALARMS .

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

Примечание: это намерение доступно в Android 4.4 (уровень API 19) и выше.

Действие
ACTION_SHOW_ALARMS
URI данных
Никто
Тип MIME
Никто

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Календарь

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

Добавить событие в календарь

Чтобы добавить новое событие в календарь пользователя, используйте действие ACTION_INSERT и укажите URI данных с помощью Events.CONTENT_URI . Затем вы можете указать различные сведения о событии, используя следующие дополнительные функции.

Действие
ACTION_INSERT
URI данных
Events.CONTENT_URI
Тип MIME
"vnd.android.cursor.dir/event"
Дополнительно
EXTRA_EVENT_ALL_DAY
Логическое значение, указывающее, является ли это событие событием на весь день.
EXTRA_EVENT_BEGIN_TIME
Время начала события (миллисекунды с начала эпохи).
EXTRA_EVENT_END_TIME
Время окончания события (миллисекунды с начала эпохи).
TITLE
Название мероприятия.
DESCRIPTION
Описание события.
EVENT_LOCATION
Место проведения мероприятия.
EXTRA_EMAIL
Список адресов электронной почты приглашенных лиц, разделенных запятыми.

Более подробную информацию о событиях можно указать с помощью констант, определенных в классе CalendarContract.EventsColumns .

Пример намерения:

Котлин

fun addEvent(title: String, location: String, begin: Long, end: Long) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        data = Events.CONTENT_URI
        putExtra(Events.TITLE, title)
        putExtra(Events.EVENT_LOCATION, location)
        putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
        putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void addEvent(String title, String location, long begin, long end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Камера

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

Сделайте снимок или снимите видео и верните его

Чтобы открыть приложение камеры и получить полученное фото или видео, используйте действие ACTION_IMAGE_CAPTURE или ACTION_VIDEO_CAPTURE . Также укажите URI, куда камера должна сохранить фото или видео, в дополнительном параметре EXTRA_OUTPUT .

Действие
ACTION_IMAGE_CAPTURE или
ACTION_VIDEO_CAPTURE
Схема URI данных
Никто
Тип MIME
Никто
Дополнительно
EXTRA_OUTPUT
Расположение URI, в котором приложение камеры сохраняет файл фотографии или видео (как объект Uri ).

Когда приложение камеры успешно возвращает фокус на вашу активность (другими словами, ваше приложение получает обратный вызов onActivityResult() , вы можете получить доступ к фотографии или видео по указанному вами URI со значением EXTRA_OUTPUT .

Примечание: при использовании ACTION_IMAGE_CAPTURE для захвата фотографии камера также может вернуть уменьшенную копию или миниатюру фотографии в результате Intent , сохраненную как Bitmap в дополнительном поле с именем "data" .

Пример намерения:

Котлин

const val REQUEST_IMAGE_CAPTURE = 1
val locationForPhotos: Uri = ...

fun capturePhoto(targetFilename: String) {
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename))
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Ява

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri locationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelableExtra("data");
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Чтобы сделать это при работе на Android 12 (уровень API 31) или выше, обратитесь к следующему примеру намерения.

Пример намерения:

Котлин

val REQUEST_IMAGE_CAPTURE = 1

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Ява

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    } catch (ActivityNotFoundException e) {
        // Display error state to the user.
    }
}
</section></div>

Дополнительную информацию об использовании этого намерения для захвата фотографии, в том числе о том, как создать соответствующий Uri для расположения выходных данных, см. в разделе «Снимки» или «Снимки видео» .

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

При обработке этого намерения заставьте свою активность проверять наличие дополнительного элемента EXTRA_OUTPUT во входящем Intent , затем сохраните захваченное изображение или видео в месте, указанном этим дополнительным элементом, и вызовите setResult() с Intent , которое включает сжатую миниатюру в дополнительном элементе с именем "data" .

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

Голосовые действия Google

  • "сделать снимок"

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

Действие
INTENT_ACTION_STILL_IMAGE_CAMERA
Схема URI данных
Никто
Тип MIME
Никто
Дополнительно
Никто

Пример намерения:

Котлин

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Ява

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Запустите приложение камеры в режиме видео

Голосовые действия Google

  • "записать видео"

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

Действие
INTENT_ACTION_VIDEO_CAMERA
Схема URI данных
Никто
Тип MIME
Никто
Дополнительно
Никто

Пример намерения:

Котлин

fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

Ява

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Приложение «Контакты/люди»

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

Выберите контакт

Чтобы пользователь выбрал контакт и предоставил вашему приложению доступ ко всей контактной информации, используйте действие ACTION_PICK и укажите тип MIME Contacts.CONTENT_TYPE .

Результат Intent , переданный обратному вызову onActivityResult() содержит следующее content: URI, указывающий на выбранный контакт. Ответ предоставляет вашему приложению временные разрешения на чтение этого контакта через API поставщика контактов , даже если в вашем приложении нет разрешения READ_CONTACTS .

Совет: если вам нужен доступ только к определенной контактной информации, например к номеру телефона или адресу электронной почты, ознакомьтесь со следующим разделом о том, как выбрать определенные контактные данные .

Действие
ACTION_PICK
Схема URI данных
Никто
Тип MIME
Contacts.CONTENT_TYPE

Пример намерения:

Котлин

const val REQUEST_SELECT_CONTACT = 1

fun selectContact() {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        val contactUri: Uri = data.data
        // Do something with the selected contact at contactUri.
        //...
    }
}

Ява

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri.
        ...
    }
}

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

При получении URI контакта с помощью этого намерения разрешение READ_CONTACTS обычно не требуется для чтения основных данных о контакте, таких как отображаемое имя и наличие звёздочки. Однако, если вы пытаетесь прочитать более конкретные данные о контакте, например номер телефона или адрес электронной почты, разрешение READ_CONTACTS необходимо.

Выберите конкретные контактные данные

Чтобы пользователь мог выбрать определенную информацию из контакта, например номер телефона, адрес электронной почты или другой тип данных, используйте действие ACTION_PICK и укажите тип MIME для одного из следующих типов контента, например CommonDataKinds.Phone.CONTENT_TYPE , чтобы получить номер телефона контакта.

Примечание: во многих случаях вашему приложению необходимо разрешение READ_CONTACTS для просмотра определенной информации о конкретном контакте.

Если вам нужно получить из контакта только один тип данных, этот метод с использованием CONTENT_TYPE из классов ContactsContract.CommonDataKinds более эффективен, чем использование Contacts.CONTENT_TYPE , как показано в предыдущем разделе. Результат обеспечивает прямой доступ к нужным данным без необходимости выполнять более сложный запрос к Contacts Provider .

Результат Intent , переданный обратному вызову onActivityResult() содержит следующее content: URI, указывающий на выбранные контактные данные. Ответ предоставляет вашему приложению временные разрешения на чтение этих контактных данных, даже если у него нет разрешения READ_CONTACTS .

Действие
ACTION_PICK
Схема URI данных
Никто
Тип MIME
CommonDataKinds.Phone.CONTENT_TYPE
Выбрать из контактов по номеру телефона.
CommonDataKinds.Email.CONTENT_TYPE
Выберите из контактов с адресом электронной почты.
CommonDataKinds.StructuredPostal.CONTENT_TYPE
Выбрать из контактов с почтовым адресом.

Или одно из многих других значений CONTENT_TYPE в ContactsContract .

Пример намерения:

Котлин

const val REQUEST_SELECT_PHONE_NUMBER = 1

fun selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = CommonDataKinds.Phone.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        val contactUri: Uri = data.data
        val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER)
        contentResolver.query(contactUri, projection, null, null, null).use { cursor ->
            // If the cursor returned is valid, get the phone number.
            if (cursor.moveToFirst()) {
                val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER)
                val number = cursor.getString(numberIndex)
                // Do something with the phone number.
                ...
            }
        }
    }
}

Ява

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number.
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number.
            //...
        }
    }
}

Просмотреть контакт

Чтобы отобразить сведения об известном контакте, используйте действие ACTION_VIEW и укажите контакт с content: URI в качестве данных намерения.

Существует два основных способа первоначального получения URI контакта:

  • Используйте URI контакта, возвращаемый действием ACTION_PICK , показанным в предыдущем разделе. Этот подход не требует никаких разрешений для приложения.
  • Доступ к списку всех контактов напрямую, как описано в разделе Получение списка контактов . Для этого подхода требуется разрешение READ_CONTACTS .
Действие
ACTION_VIEW
Схема URI данных
content:<URI>
Тип MIME
Нет. Тип определяется на основе URI контакта.

Пример намерения:

Котлин

fun viewContact(contactUri: Uri) {
    val intent = Intent(Intent.ACTION_VIEW, contactUri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Редактировать существующий контакт

Чтобы отредактировать известный контакт, используйте действие ACTION_EDIT , укажите контакт с URI content: в качестве данных намерения и включите любую известную контактную информацию в дополнительные данные, указанные константами в ContactsContract.Intents.Insert .

Существует два основных способа первоначального получения URI контакта:

  • Используйте URI контакта, возвращаемый действием ACTION_PICK , показанным в предыдущем разделе. Этот подход не требует никаких разрешений для приложения.
  • Доступ к списку всех контактов напрямую, как описано в разделе Получение списка контактов . Для этого подхода требуется разрешение READ_CONTACTS .
Действие
ACTION_EDIT
Схема URI данных
content:<URI>
Тип MIME
Тип выводится из URI контакта.
Дополнительно
Один или несколько дополнительных параметров, определенных в ContactsContract.Intents.Insert , чтобы можно было заполнить поля контактных данных.

Пример намерения:

Котлин

fun editContact(contactUri: Uri, email: String) {
    val intent = Intent(Intent.ACTION_EDIT).apply {
        data = contactUri
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void editContact(Uri contactUri, String email) {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Дополнительную информацию о том, как редактировать контакт, читайте в статье Изменение контактов с помощью намерений .

Вставить контакт

Чтобы вставить новый контакт, используйте действие ACTION_INSERT , укажите Contacts.CONTENT_TYPE в качестве типа MIME и включите любую известную контактную информацию в дополнительные данные, указанные константами в ContactsContract.Intents.Insert .

Действие
ACTION_INSERT
Схема URI данных
Никто
Тип MIME
Contacts.CONTENT_TYPE
Дополнительно
Один или несколько дополнительных параметров, определенных в ContactsContract.Intents.Insert .

Пример намерения:

Котлин

fun insertContact(name: String, email: String) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void insertContact(String name, String email) {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Дополнительную информацию о том, как вставить контакт, читайте в разделе Изменение контактов с помощью намерений .

Электронная почта

Составление электронного письма с дополнительными вложениями — распространённое действие в почтовых приложениях. Создайте фильтр намерений, чтобы рекламировать возможность вашего приложения выполнять это действие, используя информацию из следующего раздела.

Составьте электронное письмо с дополнительными вложениями

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

Действие
ACTION_SENDTO (без вложения) или
ACTION_SEND (для одного вложения) или
ACTION_SEND_MULTIPLE (для нескольких вложений)
Схема URI данных
Никто
Тип MIME
"text/plain"
"*/*"
Дополнительно
Intent.EXTRA_EMAIL
Массив строк всех адресов электронной почты получателей «Кому».
Intent.EXTRA_CC
Массив строк всех адресов электронной почты получателей «CC».
Intent.EXTRA_BCC
Массив строк всех адресов электронной почты получателей «BCC».
Intent.EXTRA_SUBJECT
Строка с темой письма.
Intent.EXTRA_TEXT
Строка с телом письма.
Intent.EXTRA_STREAM
Uri , указывающий на вложение. При использовании действия ACTION_SEND_MULTIPLE это будет ArrayList , содержащий несколько объектов Uri .

Пример намерения:

Котлин

fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Если вы хотите быть уверены, что ваше намерение обрабатывается только приложением электронной почты, а не приложением для обмена текстовыми сообщениями или социальным приложением, то используйте действие ACTION_SENDTO и включите схему данных "mailto:" , как показано в следующем примере:

Котлин

fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:") // Only email apps handle this.
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // Only email apps handle this.
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Хранилище файлов

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

Получить определенный тип файла

Чтобы запросить у пользователя выбор файла, например документа или фотографии, и вернуть ссылку на ваше приложение, используйте действие ACTION_GET_CONTENT и укажите нужный тип MIME. Ссылка на файл, возвращаемая в ваше приложение, является временной для текущего жизненного цикла вашей активности, поэтому, если вы захотите получить к ней доступ позже, необходимо импортировать копию, которую можно будет прочитать позже.

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

Результат, передаваемый методу onActivityResult() включает данные с URI, указывающим на файл. URI может быть любым, например, http: URI, file: URI или content: URI. Однако, если вы хотите ограничить выбор только теми файлами, которые доступны через поставщика контента ( content: URI) и доступны как файловый поток с помощью openFileDescriptor() , добавьте категорию CATEGORY_OPENABLE к своему намерению.

В Android 4.3 (уровень API 18) и выше вы также можете разрешить пользователю выбирать несколько файлов, добавив EXTRA_ALLOW_MULTIPLE к намерению со значением true . После этого вы сможете получить доступ к каждому из выбранных файлов в объекте ClipData , возвращаемом методом getClipData() .

Действие
ACTION_GET_CONTENT
Схема URI данных
Никто
Тип MIME
Тип MIME, соответствующий типу файла, который необходимо выбрать пользователю.
Дополнительно
EXTRA_ALLOW_MULTIPLE
Логическое значение, которое определяет, может ли пользователь выбрать более одного файла одновременно.
EXTRA_LOCAL_ONLY
Логическое значение, которое определяет, должен ли возвращаемый файл быть доступен непосредственно с устройства, а не требовать загрузки с удаленной службы.
Категория (необязательно)
CATEGORY_OPENABLE
Возвращать только «открываемые» файлы, которые можно представить в виде файлового потока с помощью openFileDescriptor() .

Пример намерения получить фотографию:

Котлин

const val REQUEST_IMAGE_GET = 1

fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        val fullPhotoUri: Uri = data.data
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

Ява

static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

Пример фильтра намерений для возврата фотографии:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor(). -->
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

Открыть определенный тип файла

Вместо получения копии файла, который необходимо импортировать в приложение, с помощью действия ACTION_GET_CONTENT , на устройствах Android 4.4 и выше вы можете запросить открытие файла, управляемого другим приложением, с помощью действия ACTION_OPEN_DOCUMENT , указав тип MIME. Чтобы пользователь также мог создать новый документ, в который ваше приложение сможет записывать данные, используйте действие ACTION_CREATE_DOCUMENT .

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

В то время как намерение, переданное в метод onActivityResult() из действия ACTION_GET_CONTENT , может возвращать URI любого типа, результирующее намерение от ACTION_OPEN_DOCUMENT и ACTION_CREATE_DOCUMENT всегда указывает выбранный файл как URI content: поддерживаемый DocumentsProvider . Вы можете открыть файл с помощью openFileDescriptor() и запросить его данные, используя столбцы из DocumentsContract.Document .

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

Вы также можете разрешить пользователю выбирать несколько файлов, добавив EXTRA_ALLOW_MULTIPLE к намерению со значением true . Если пользователь выбирает только один элемент, его можно получить с помощью getData() . Если пользователь выбирает более одного элемента, getData() возвращает null, и вместо этого необходимо извлечь каждый элемент из объекта ClipData , возвращаемого getClipData() .

Примечание: В вашем намерении необходимо указать тип MIME и объявить категорию CATEGORY_OPENABLE . При необходимости можно указать несколько типов MIME, добавив массив типов MIME с дополнительным параметром EXTRA_MIME_TYPES . В этом случае необходимо установить основной тип MIME в setType() равным "*/*" .

Действие
ACTION_OPEN_DOCUMENT или
ACTION_CREATE_DOCUMENT
Схема URI данных
Никто
Тип MIME
Тип MIME, соответствующий типу файла, который необходимо выбрать пользователю.
Дополнительно
EXTRA_MIME_TYPES
Массив MIME-типов, соответствующих типам файлов, запрашиваемых вашим приложением. При использовании этого дополнения необходимо установить основной MIME-тип в setType() на "*/*" .
EXTRA_ALLOW_MULTIPLE
Логическое значение, которое определяет, может ли пользователь выбрать более одного файла одновременно.
EXTRA_TITLE
Для использования с ACTION_CREATE_DOCUMENT для указания начального имени файла.
EXTRA_LOCAL_ONLY
Логическое значение, которое определяет, должен ли возвращаемый файл быть доступен непосредственно с устройства, а не требовать загрузки с удаленной службы.
Категория
CATEGORY_OPENABLE
Возвращать только «открываемые» файлы, которые можно представить в виде файлового потока с помощью openFileDescriptor() .

Пример намерения получить фотографию:

Котлин

const val REQUEST_IMAGE_OPEN = 1

fun selectImage2() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        type = "image/*"
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) {
        val fullPhotoUri: Uri = data.data
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

Ява

static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

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

Чтобы предоставить файлы вашего приложения в этом пользовательском интерфейсе и разрешить другим приложениям открывать их, необходимо реализовать DocumentsProvider и включить фильтр намерений для PROVIDER_INTERFACE ( "android.content.action.DOCUMENTS_PROVIDER" ), как показано в следующем примере:

<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

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

Местные действия

Вызов автомобиля — распространённое локальное действие. Создайте фильтр намерений, чтобы рекламировать возможность выполнения этого действия в вашем приложении, используя информацию из следующего раздела.

Вызовите машину

Голосовые действия Google

  • "вызовите мне такси"
  • "вызови мне машину"

(Только Wear OS)

Чтобы вызвать такси, используйте действие ACTION_RESERVE_TAXI_RESERVATION .

Примечание: перед выполнением этого действия приложения должны запрашивать подтверждение у пользователя.

Действие
ACTION_RESERVE_TAXI_RESERVATION
URI данных
Никто
Тип MIME
Никто
Дополнительно
Никто

Пример намерения:

Котлин

fun callCar() {
    val intent = Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void callCar() {
    Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Карты

Отображение местоположения на карте — распространённое действие для картографических приложений. Создайте фильтр намерений, чтобы рекламировать возможность вашего приложения выполнять это действие, используя информацию из следующего раздела.

Показать местоположение на карте

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

Действие
ACTION_VIEW
Схема URI данных
geo: latitude , longitude
Показать карту на заданной долготе и широте.

Пример: "geo:47.6,-122.3"

geo: latitude , longitude ?z= zoom
Показать карту на заданных широте и долготе с определённым уровнем масштабирования. Уровень масштабирования 1 отображает всю Землю с центром в заданных координатах широты и долготы . Максимальный (ближайший) уровень масштабирования — 23.

Пример: "geo:47.6,-122.3?z=11"

geo:0,0?q=lat,lng(label)
Показывать карту на заданной долготе и широте со строковой меткой.

Пример: "geo:0,0?q=34.99,-106.61(Treasure)"

geo:0,0?q=my+street+address
Показывать местоположение для «моего почтового адреса», который может быть конкретным адресом или запросом местоположения.

Пример: "geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"

Примечание: Все строки, передаваемые в geo URI, должны быть закодированы. Например, строка 1st & Pike, Seattle преобразуется 1st%20%26%20Pike%2C%20Seattle . Пробелы в строке кодируются %20 или заменяются знаком плюс ( + ).

Тип MIME
Никто

Пример намерения:

Котлин

fun showMap(geoLocation: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = geoLocation
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Музыка или видео

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

Воспроизвести медиафайл

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

Действие
ACTION_VIEW
Схема URI данных
file: <URI>
content: <URI>
http: <URL>
Тип MIME
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
Или любой другой, требуемый вашим приложением.

Пример намерения:

Котлин

fun playMedia(file: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = file
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Воспроизведение музыки на основе поискового запроса

Голосовые действия Google

  • "воспроизвести Майкла Джексона Билли Джин"

Чтобы воспроизвести музыку по поисковому запросу, используйте намерение INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH . Приложение может активировать это намерение в ответ на голосовую команду пользователя воспроизвести музыку. Принимающее это намерение приложение выполняет поиск в своём инвентаре, чтобы сопоставить существующий контент с заданным запросом, и начинает его воспроизведение.

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

Действие
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
Схема URI данных
Никто
Тип MIME
Никто
Дополнительно
MediaStore.EXTRA_MEDIA_FOCUS (обязательно)

Указывает режим поиска: ищет ли пользователь конкретного исполнителя, альбом, песню или плейлист. Большинство режимов поиска требуют дополнительных данных. Например, если пользователь хочет послушать конкретную песню, намерение может содержать три дополнительных параметра: название песни, исполнителя и альбом. Это намерение поддерживает следующие режимы поиска для каждого значения EXTRA_MEDIA_FOCUS :

Любой - "vnd.android.cursor.item/*"

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

Дополнительные услуги:

  • QUERY (обязательно): пустая строка. Этот дополнительный параметр всегда предоставляется для обеспечения обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Неструктурированный - "vnd.android.cursor.item/*"

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

Дополнительные услуги:

  • QUERY (обязательно): строка, содержащая любую комбинацию исполнителя, альбома, названия песни или жанра.

Жанр - Audio.Genres.ENTRY_CONTENT_TYPE

Включайте музыку определенного жанра.

Дополнительные услуги:

  • "android.intent.extra.genre" (обязательно) — жанр.
  • QUERY (обязательно): жанр. Этот дополнительный параметр всегда предоставляется для обеспечения обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Исполнитель - Audio.Artists.ENTRY_CONTENT_TYPE

Воспроизвести музыку определенного исполнителя.

Дополнительные услуги:

  • EXTRA_MEDIA_ARTIST (обязательно): художник.
  • "android.intent.extra.genre" : жанр.
  • QUERY (обязательно): строка, содержащая любую комбинацию исполнителя или жанра. Это дополнительное поле всегда предоставляется для обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Альбом - Audio.Albums.ENTRY_CONTENT_TYPE

Воспроизвести музыку из определенного альбома.

Дополнительные услуги:

  • EXTRA_MEDIA_ALBUM (обязательно): альбом.
  • EXTRA_MEDIA_ARTIST : художник.
  • "android.intent.extra.genre" : жанр.
  • QUERY (обязательно): строка, содержащая любую комбинацию названия альбома или исполнителя. Это дополнение всегда предоставляется для обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Песня - "vnd.android.cursor.item/audio"

Включите определенную песню.

Дополнительные услуги:

  • EXTRA_MEDIA_ALBUM : альбом.
  • EXTRA_MEDIA_ARTIST : художник.
  • "android.intent.extra.genre" : жанр.
  • EXTRA_MEDIA_TITLE (обязательно): название песни.
  • QUERY (обязательно): строка, содержащая любую комбинацию названия альбома, исполнителя, жанра или названия. Этот дополнительный параметр всегда предоставляется для обеспечения обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Плейлист - Audio.Playlists.ENTRY_CONTENT_TYPE

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

Дополнительные услуги:

  • EXTRA_MEDIA_ALBUM : альбом.
  • EXTRA_MEDIA_ARTIST : художник.
  • "android.intent.extra.genre" : жанр.
  • "android.intent.extra.playlist" : плейлист.
  • EXTRA_MEDIA_TITLE : название песни, на которой основан плейлист.
  • QUERY (обязательно): строка, содержащая любую комбинацию альбома, исполнителя, жанра, плейлиста или названия. Этот дополнительный параметр всегда предоставляется для обратной совместимости. Существующие приложения, не поддерживающие режимы поиска, могут обрабатывать это намерение как неструктурированный поиск.

Пример намерения:

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

Котлин

fun playSearchArtist(artist: String) {
    val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).apply {
        putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)
        putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist)
        putExtra(SearchManager.QUERY, artist)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void playSearchArtist(String artist) {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
    intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
                    MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE);
    intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
    intent.putExtra(SearchManager.QUERY, artist);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

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

Котлин

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (intent.action.compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        val mediaFocus: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)
        val query: String? = intent.getStringExtra(SearchManager.QUERY)

        // Some of these extras might not be available depending on the search mode.
        val album: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM)
        val artist: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST)
        val genre: String? = intent.getStringExtra("android.intent.extra.genre")
        val playlist: String? = intent.getStringExtra("android.intent.extra.playlist")
        val title: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE)

        // Determine the search mode and use the corresponding extras.
        when {
            mediaFocus == null -> {
                // 'Unstructured' search mode (backward compatible)
                playUnstructuredSearch(query)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/*") == 0 -> {
                if (query?.isNotEmpty() == true) {
                    // 'Unstructured' search mode.
                    playUnstructuredSearch(query)
                } else {
                    // 'Any' search mode.
                    playResumeLastPlaylist()
                }
            }
            mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Genre' search mode.
                playGenre(genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Artist' search mode.
                playArtist(artist, genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Album' search mode.
                playAlbum(album, artist)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0 -> {
                // 'Song' search mode.
                playSong(album, artist, genre, title)
            }
            mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Playlist' search mode.
                playPlaylist(album, artist, genre, playlist, title)
            }
        }
    }
}

Ява

protected void onCreate(Bundle savedInstanceState) {
    //...
    Intent intent = this.getIntent();
    if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Some of these extras might not be available depending on the search mode.
        String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
        String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
        String genre = intent.getStringExtra("android.intent.extra.genre");
        String playlist = intent.getStringExtra("android.intent.extra.playlist");
        String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);

        // Determine the search mode and use the corresponding extras.
        if (mediaFocus == null) {
            // 'Unstructured' search mode (backward compatible).
            playUnstructuredSearch(query);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
            if (query.isEmpty()) {
                // 'Any' search mode.
                playResumeLastPlaylist();
            } else {
                // 'Unstructured' search mode.
                playUnstructuredSearch(query);
            }

        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
            // 'Genre' search mode.
            playGenre(genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Artist' search mode.
            playArtist(artist, genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
            // 'Album' search mode.
            playAlbum(album, artist);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
            // 'Song' search mode.
            playSong(album, artist, genre, title);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Playlist' search mode.
            playPlaylist(album, artist, genre, playlist, title);
        }
    }
}

Новая заметка

Создание заметки — распространённое действие в приложениях для заметок. Создайте фильтр намерений, чтобы указать, что ваше приложение может выполнять это действие, используя информацию из следующего раздела.

Создать заметку

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

Примечание: перед выполнением этого действия приложения должны запрашивать подтверждение у пользователя.

Действие
ACTION_CREATE_NOTE
Схема URI данных
Никто
Тип MIME
PLAIN_TEXT_TYPE
"*/*"
Дополнительно
EXTRA_NAME
Строка, указывающая название или тему заметки.
EXTRA_TEXT
Строка, указывающая текст заметки.

Пример намерения:

Котлин

fun createNote(subject: String, text: String) {
    val intent = Intent(NoteIntents.ACTION_CREATE_NOTE).apply {
        putExtra(NoteIntents.EXTRA_NAME, subject)
        putExtra(NoteIntents.EXTRA_TEXT, text)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void createNote(String subject, String text) {
    Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE)
            .putExtra(NoteIntents.EXTRA_NAME, subject)
            .putExtra(NoteIntents.EXTRA_TEXT, text);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />
    </intent-filter>
</activity>

Телефон

Совершение звонка — распространённое действие в телефонных приложениях. Создайте фильтр намерений, чтобы рекламировать возможность вашего приложения выполнять это действие, используя информацию из следующего раздела.

Инициировать телефонный звонок

Чтобы открыть приложение «Телефон» и набрать номер, используйте действие ACTION_DIAL и укажите номер телефона, используя следующую схему URI. При открытии приложения «Телефон» отображается номер телефона, и пользователю необходимо нажать кнопку «Вызов» , чтобы начать звонок.

Голосовые действия Google

  • "позвоните 555-5555"
  • "позвони Бобу"
  • "вызов голосовой почты"

Чтобы совершить телефонный звонок напрямую, используйте действие ACTION_CALL и укажите номер телефона, используя следующую схему URI. При открытии приложения «Телефон» оно начинает телефонный звонок. Пользователю не нужно нажимать кнопку «Позвонить» .

Действие ACTION_CALL требует добавления разрешения CALL_PHONE в файл манифеста:

<uses-permission android:name="android.permission.CALL_PHONE" />
Действие
  • ACTION_DIAL — открывает приложение для набора номера или телефона.
  • ACTION_CALL — Совершает телефонный звонок (требуется разрешение CALL_PHONE )
Схема URI данных
  • tel:<phone-number>
  • voicemail:<phone-number>
Тип MIME
Никто

Допустимые номера телефонов — это номера, определённые в документе IETF RFC 3966. Допустимые примеры включают следующее:

  • tel:2125551212
  • tel:(212) 555 1212

Номеронабиратель приложения «Телефон» хорошо справляется с нормализацией схем, таких как телефонные номера. Поэтому описанная схема не является строго обязательной в методе Uri.parse() . Однако, если вы не пробовали схему или не уверены, можно ли её обработать, используйте метод Uri.fromParts() .

Пример намерения:

Котлин

fun dialPhoneNumber(phoneNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL).apply {
        data = Uri.parse("tel:$phoneNumber")
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

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

Поиск с использованием определенного приложения

Голосовые действия Google

  • "найдите видео с кошками на myvideoapp"

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

Примечание: Мы не рекомендуем использовать действие SEARCH_ACTION для поиска в приложениях. Вместо этого реализуйте действие GET_THING , чтобы использовать встроенную поддержку поиска в приложениях Google Assistant. Подробнее см. в документации по действиям в приложениях Google Assistant.

Действие
"com.google.android.gms.actions.SEARCH_ACTION"
Поддержка поисковых запросов с помощью Google Voice Actions.
Дополнительно
QUERY
Строка, содержащая поисковый запрос.

Пример фильтра намерений:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

Выполните поиск в Интернете

Чтобы инициировать веб-поиск, используйте действие ACTION_WEB_SEARCH и укажите строку поиска в дополнительном SearchManager.QUERY .

Действие
ACTION_WEB_SEARCH
Схема URI данных
Никто
Тип MIME
Никто
Дополнительно
SearchManager.QUERY
Строка поиска.

Пример намерения:

Котлин

fun searchWeb(query: String) {
    val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
        putExtra(SearchManager.QUERY, query)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Настройки

Чтобы открыть экран в системном приложении «Настройки», когда ваше приложение требует от пользователя что-то изменить, используйте одно из следующих действий намерения:

Действие
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS

Дополнительные доступные экраны настроек см. в документации Settings .

Схема URI данных
Никто
Тип MIME
Никто

Пример намерения:

Котлин

fun openWifiSettings() {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void openWifiSettings() {
    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Текстовые сообщения

Создание SMS/MMS-сообщений с вложением — распространённое действие в приложениях для обмена текстовыми сообщениями. Создайте фильтр намерений, чтобы рекламировать возможность вашего приложения выполнять это действие, используя информацию из следующего раздела.

Составьте SMS/MMS-сообщение с вложением

Чтобы инициировать текстовое сообщение SMS или MMS, используйте одно из следующих действий намерения и укажите данные сообщения, такие как номер телефона, тема и текст сообщения, с помощью следующих дополнительных клавиш.

Действие
ACTION_SENDTO или
ACTION_SEND или
ACTION_SEND_MULTIPLE
Схема URI данных
sms: <phone_number>
smsto: <phone_number>
mms: <phone_number>
mmsto: <phone_number>

Все эти схемы обрабатываются одинаково.

Тип MIME
"text/plain"
"image/*"
"video/*"
Дополнительно
"subject"
Строка темы сообщения (обычно только для MMS).
"sms_body"
Строка для текстового сообщения.
EXTRA_STREAM
Uri , указывающий на изображение или видео для прикрепления. При использовании действия ACTION_SEND_MULTIPLE это дополнительный объект типа ArrayList , содержащий объекты Uri , указывающие на изображения или видео для прикрепления.

Пример намерения:

Котлин

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        type = HTTP.PLAIN_TEXT_TYPE
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Если вы хотите быть уверены, что ваше намерение обрабатывается только приложением для обмена текстовыми сообщениями, а не другими приложениями электронной почты или социальных сетей, то используйте действие ACTION_SENDTO и включите схему данных "smsto:" , как показано в следующем примере:

Котлин

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        data = Uri.parse("smsto:")  // Only SMS apps respond to this.
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // Only SMS apps respond to this.
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

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

Примечание: Если вы разрабатываете приложение для обмена SMS/MMS-сообщениями, необходимо реализовать фильтры намерений для нескольких дополнительных действий, чтобы оно стало доступным в качестве приложения SMS по умолчанию на Android 4.4 и более поздних версиях. Подробнее см. в документации Telephony .

Веб-браузер

Загрузка URL-адреса — распространённое действие для приложений веб-браузера. Создайте фильтр намерений, чтобы объявить о возможности вашего приложения выполнять это действие, используя информацию из следующего раздела.

Загрузить веб-URL

Голосовые действия Google

  • "открыть example.com"

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

Действие
ACTION_VIEW
Схема URI данных
http: <URL>
https: <URL>
Тип MIME
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

Пример намерения:

Котлин

fun openWebPage(url: String) {
    val webpage: Uri = Uri.parse(url)
    val intent = Intent(Intent.ACTION_VIEW, webpage)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Ява

public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Пример фильтра намерений:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

Совет: Если ваше приложение для Android предоставляет функционал, аналогичный вашему веб-сайту, включите фильтр намерений для URL-адресов, ведущих на ваш веб-сайт. Тогда, если у пользователей установлено ваше приложение, ссылки из электронных писем или других веб-страниц, ведущие на ваш сайт, будут открывать ваше приложение для Android, а не вашу веб-страницу. Подробнее см. в статье «Обработка ссылок в приложениях Android» .

Начиная с Android 12 (уровень API 31), общее веб-намерение преобразуется в активность в вашем приложении только в том случае, если ваше приложение одобрено для домена, указанного в этом веб-намерении. Если ваше приложение не одобрено для домена, веб-намерение преобразуется в приложение браузера пользователя по умолчанию.

Проверка намерений с помощью Android Debug Bridge

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

  1. Настройте Android-устройство для разработки или используйте виртуальное устройство .
  2. Установите версию вашего приложения, которая обрабатывает те намерения, которые вы хотите поддерживать.
  3. Запустить намерение с помощью adb :
    adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \
      -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
    

    Например:

    adb shell am start -a android.intent.action.DIAL \
      -d tel:555-5555 -n org.example.MyApp/.MyActivity
    
  4. Если вы определили требуемые фильтры намерений, обработайте намерения.

Для получения дополнительной информации см. Команды выпуска Shell .