В Android 11 и более поздних версиях функция быстрого доступа к элементам управления устройствами позволяет пользователю быстро просматривать и управлять внешними устройствами, такими как светильники, термостаты и камеры, с помощью возможностей пользователя за три взаимодействия с помощью панели запуска по умолчанию. OEM-производитель устройства выбирает, какую программу запуска использовать. Агрегаторы устройств, например Google Home, и приложения сторонних поставщиков могут предоставлять устройства для отображения в этом пространстве. На этой странице показано, как разместить элементы управления устройством в этом пространстве и связать их с вашим приложением управления.
Чтобы добавить эту поддержку, создайте и объявите ControlsProviderService
. Создайте элементы управления, которые поддерживает ваше приложение, на основе предопределенных типов элементов управления, а затем создайте издателей для этих элементов управления.
Пользовательский интерфейс
Устройства отображаются в разделе «Устройства» в виде шаблонных виджетов. Доступны пять виджетов управления устройством, как показано на следующем рисунке:
![]() | ![]() | ![]() |
![]() | ![]() |
Прикосновение и удерживание виджета приведет вас к приложению для более глубокого управления. Вы можете настроить значок и цвет каждого виджета, но для лучшего взаимодействия с пользователем используйте значок и цвет по умолчанию, если набор по умолчанию соответствует устройству.

Создать сервис
В этом разделе показано, как создать ControlsProviderService
. Эта служба сообщает пользовательскому интерфейсу системы Android, что ваше приложение содержит элементы управления устройством, которые должны отображаться в области «Элементы управления устройством» пользовательского интерфейса Android.
API ControlsProviderService
предполагает знакомство с реактивными потоками, как определено в проекте Reactive Streams GitHub и реализовано в интерфейсах Java 9 Flow . API построен на основе следующих концепций:
- Издатель: ваше приложение является издателем.
- Подписчик: системный пользовательский интерфейс является подписчиком и может запрашивать у издателя ряд элементов управления.
- Подписка: период времени, в течение которого издатель может отправлять обновления для системного пользовательского интерфейса. Либо издатель, либо подписчик могут закрыть это окно.
Объявить службу
Ваше приложение должно объявить службу, например MyCustomControlService
, в своем манифесте приложения.
Служба должна включать фильтр намерений для ControlsProviderService
. Этот фильтр позволяет приложениям вносить элементы управления в системный пользовательский интерфейс.
Вам также понадобится label
, которая отображается в элементах управления пользовательского интерфейса системы.
В следующем примере показано, как объявить службу:
<service
android:name="MyCustomControlService"
android:label="My Custom Controls"
android:permission="android.permission.BIND_CONTROLS"
android:exported="true"
>
<intent-filter>
<action android:name="android.service.controls.ControlsProviderService" />
</intent-filter>
</service>
Затем создайте новый файл Kotlin с именем MyCustomControlService.kt
и расширите его ControlsProviderService()
:
class MyCustomControlService : ControlsProviderService() {
...
}
public class MyCustomJavaControlService extends ControlsProviderService {
...
}
Выберите правильный тип управления
API предоставляет методы компоновщика для создания элементов управления. Чтобы заполнить конструктор, определите устройство, которым вы хотите управлять, и способ взаимодействия с ним пользователя. Выполните следующие шаги:
- Выберите тип устройства, которое представляет элемент управления. Класс
DeviceTypes
представляет собой перечисление всех поддерживаемых устройств. Тип используется для определения значков и цветов устройства в пользовательском интерфейсе. - Определите имя пользователя, местоположение устройства (например, кухня) и другие текстовые элементы пользовательского интерфейса, связанные с элементом управления.
- Выберите лучший шаблон для поддержки взаимодействия с пользователем. Элементам управления назначается
ControlTemplate
из приложения. Этот шаблон напрямую показывает пользователю состояние элемента управления, а также доступные методы ввода, то естьControlAction
. В следующей таблице представлены некоторые доступные шаблоны и действия, которые они поддерживают:
Шаблон | Действие | Описание |
ControlTemplate.getNoTemplateObject() | None | Приложение может использовать это для передачи информации об элементе управления, но пользователь не может с ним взаимодействовать. |
ToggleTemplate | BooleanAction | Представляет элемент управления, который можно переключать между включенным и отключенным состояниями. Объект BooleanAction содержит поле, которое изменяется, отображая запрошенное новое состояние, когда пользователь касается элемента управления. |
RangeTemplate | FloatAction | Представляет виджет ползунка с указанными минимальными, максимальными значениями и значениями шага. Когда пользователь взаимодействует с ползунком, отправьте новый объект FloatAction обратно в приложение с обновленным значением. |
ToggleRangeTemplate | BooleanAction , FloatAction | Этот шаблон представляет собой комбинацию ToggleTemplate и RangeTemplate . Он поддерживает сенсорные события, а также ползунок, например, для управления регулируемой подсветкой. |
TemperatureControlTemplate | ModeAction , BooleanAction , FloatAction | Помимо инкапсуляции предыдущих действий, этот шаблон позволяет пользователю установить режим, например обогрев, охлаждение, обогрев/охлаждение, эко или выключение. |
StatelessTemplate | CommandAction | Используется для обозначения элемента управления, который обеспечивает сенсорное управление, но состояние которого невозможно определить, например, пульт дистанционного управления ИК-телевизором. Вы можете использовать этот шаблон для определения процедуры или макроса, который представляет собой совокупность элементов управления и изменений состояния. |
Используя эту информацию, вы можете создать элемент управления:
- Используйте класс построителя
Control.StatelessBuilder
, если состояние элемента управления неизвестно. - Используйте класс построителя
Control.StatefulBuilder
, если известно состояние элемента управления.
Например, чтобы управлять умной лампочкой и термостатом, добавьте в MyCustomControlService
следующие константы:
private const val LIGHT_ID = 1234
private const val LIGHT_TITLE = "My fancy light"
private const val LIGHT_TYPE = DeviceTypes.TYPE_LIGHT
private const val THERMOSTAT_ID = 5678
private const val THERMOSTAT_TITLE = "My fancy thermostat"
private const val THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT
class MyCustomControlService : ControlsProviderService() {
...
}
public class MyCustomJavaControlService extends ControlsProviderService {
private final int LIGHT_ID = 1337;
private final String LIGHT_TITLE = "My fancy light";
private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
private final int THERMOSTAT_ID = 1338;
private final String THERMOSTAT_TITLE = "My fancy thermostat";
private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
...
}
Создайте издателей для элементов управления
После создания элемента управления ему потребуется издатель. Издатель сообщает системному пользовательскому интерфейсу о существовании элемента управления. Класс ControlsProviderService
имеет два метода издателя, которые необходимо переопределить в коде приложения:
-
createPublisherForAllAvailable()
: создаетPublisher
для всех элементов управления, доступных в вашем приложении. ИспользуйтеControl.StatelessBuilder()
для создания объектовControl
для этого издателя. -
createPublisherFor()
: создаетPublisher
для списка заданных элементов управления, определяемых их строковыми идентификаторами. ИспользуйтеControl.StatefulBuilder
для создания этих объектовControl
, поскольку издатель должен назначить состояние каждому элементу управления.
Создать издателя
Когда ваше приложение впервые публикует элементы управления в системном пользовательском интерфейсе, оно не знает состояния каждого элемента управления. Получение состояния может оказаться трудоемкой операцией, включающей множество переходов в сети поставщика устройства. Используйте метод createPublisherForAllAvailable()
чтобы объявить системе доступные элементы управления. Этот метод использует класс построителя Control.StatelessBuilder
, поскольку состояние каждого элемента управления неизвестно.
Как только элементы управления появятся в пользовательском интерфейсе Android, пользователь сможет выбрать избранные элементы управления.
Чтобы использовать сопрограммы Kotlin для создания ControlsProviderService
, добавьте новую зависимость в свой build.gradle
:
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4")
}
После синхронизации файлов Gradle добавьте в свою Service
следующий фрагмент, чтобы реализовать createPublisherForAllAvailable()
:
class MyCustomControlService : ControlsProviderService() {
override fun createPublisherForAllAvailable(): Flow.Publisher
public class MyCustomJavaControlService extends ControlsProviderService {
private final int LIGHT_ID = 1337;
private final String LIGHT_TITLE = "My fancy light";
private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
private final int THERMOSTAT_ID = 1338;
private final String THERMOSTAT_TITLE = "My fancy thermostat";
private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
private boolean toggleState = false;
private float rangeState = 18f;
private final Map
Проведите вниз по системному меню и найдите кнопку «Управление устройством» , показанную на рис. 4:

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

Теперь реализуйте метод createPublisherFor()
, добавив в свой Service
следующее:
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job)
private val controlFlows = mutableMapOf
@NonNull
@Override
public Flow.Publisher
В этом примере метод createPublisherFor()
содержит фиктивную реализацию того, что должно делать ваше приложение: связываться с вашим устройством, чтобы получить его статус, и отправлять этот статус в систему.
Метод createPublisherFor()
использует сопрограммы и потоки Kotlin для удовлетворения требований API Reactive Streams, выполняя следующие действия:
- Создает
Flow
. - Ждет одну секунду.
- Создает и излучает состояние интеллектуального света.
- Ждет еще секунду.
- Создает и передает состояние термостата.
Обработка действий
Метод performControlAction()
сигнализирует, когда пользователь взаимодействует с опубликованным элементом управления. Тип отправленного ControlAction
определяет действие. Выполните соответствующее действие для данного элемента управления, а затем обновите состояние устройства в пользовательском интерфейсе Android.
Чтобы завершить пример, добавьте в свой Service
следующее:
override fun performControlAction(
controlId: String,
action: ControlAction,
consumer: Consumer
@Override
public void performControlAction(@NonNull String controlId, @NonNull ControlAction action, @NonNull Consumer
Запустите приложение, получите доступ к меню управления устройством и просмотрите элементы управления освещением и термостатом.

В Android 11 и более поздних версиях функция быстрого доступа к элементам управления устройствами позволяет пользователю быстро просматривать и управлять внешними устройствами, такими как светильники, термостаты и камеры, с помощью возможностей пользователя за три взаимодействия с панелью запуска по умолчанию. OEM-производитель устройства выбирает, какую программу запуска использовать. Агрегаторы устройств, например Google Home, и приложения сторонних поставщиков могут предоставлять устройства для отображения в этом пространстве. На этой странице показано, как разместить элементы управления устройством в этом пространстве и связать их с вашим приложением управления.
Чтобы добавить эту поддержку, создайте и объявите ControlsProviderService
. Создайте элементы управления, которые поддерживает ваше приложение, на основе предопределенных типов элементов управления, а затем создайте издателей для этих элементов управления.
Пользовательский интерфейс
Устройства отображаются в разделе «Устройства» в виде шаблонных виджетов. Доступны пять виджетов управления устройством, как показано на следующем рисунке:
![]() | ![]() | ![]() |
![]() | ![]() |
Прикосновение и удерживание виджета приведет вас к приложению для более глубокого управления. Вы можете настроить значок и цвет каждого виджета, но для лучшего взаимодействия с пользователем используйте значок и цвет по умолчанию, если набор по умолчанию соответствует устройству.

Создать сервис
В этом разделе показано, как создать ControlsProviderService
. Эта служба сообщает пользовательскому интерфейсу системы Android, что ваше приложение содержит элементы управления устройством, которые должны отображаться в области «Элементы управления устройством» пользовательского интерфейса Android.
API ControlsProviderService
предполагает знакомство с реактивными потоками, как определено в проекте Reactive Streams GitHub и реализовано в интерфейсах Java 9 Flow . API построен на основе следующих концепций:
- Издатель: ваше приложение является издателем.
- Подписчик: системный пользовательский интерфейс является подписчиком и может запрашивать у издателя ряд элементов управления.
- Подписка: период времени, в течение которого издатель может отправлять обновления для системного пользовательского интерфейса. Либо издатель, либо подписчик могут закрыть это окно.
Объявить службу
Ваше приложение должно объявить службу, например MyCustomControlService
, в своем манифесте приложения.
Служба должна включать фильтр намерений для ControlsProviderService
. Этот фильтр позволяет приложениям вносить элементы управления в системный пользовательский интерфейс.
Вам также понадобится label
, которая отображается в элементах управления пользовательского интерфейса системы.
В следующем примере показано, как объявить службу:
<service
android:name="MyCustomControlService"
android:label="My Custom Controls"
android:permission="android.permission.BIND_CONTROLS"
android:exported="true"
>
<intent-filter>
<action android:name="android.service.controls.ControlsProviderService" />
</intent-filter>
</service>
Затем создайте новый файл Kotlin с именем MyCustomControlService.kt
и расширите его ControlsProviderService()
:
class MyCustomControlService : ControlsProviderService() {
...
}
public class MyCustomJavaControlService extends ControlsProviderService {
...
}
Выберите правильный тип управления
API предоставляет методы компоновщика для создания элементов управления. Чтобы заполнить конструктор, определите устройство, которым вы хотите управлять, и способ взаимодействия с ним пользователя. Выполните следующие шаги:
- Выберите тип устройства, которое представляет элемент управления. Класс
DeviceTypes
представляет собой перечисление всех поддерживаемых устройств. Тип используется для определения значков и цветов устройства в пользовательском интерфейсе. - Определите имя пользователя, местоположение устройства (например, кухня) и другие текстовые элементы пользовательского интерфейса, связанные с элементом управления.
- Выберите лучший шаблон для поддержки взаимодействия с пользователем. Элементам управления назначается
ControlTemplate
из приложения. Этот шаблон напрямую показывает пользователю состояние элемента управления, а также доступные методы ввода, то естьControlAction
. В следующей таблице представлены некоторые доступные шаблоны и действия, которые они поддерживают:
Шаблон | Действие | Описание |
ControlTemplate.getNoTemplateObject() | None | Приложение может использовать это для передачи информации об элементе управления, но пользователь не может с ним взаимодействовать. |
ToggleTemplate | BooleanAction | Представляет элемент управления, который можно переключать между включенным и отключенным состояниями. Объект BooleanAction содержит поле, которое изменяется, отображая запрошенное новое состояние, когда пользователь касается элемента управления. |
RangeTemplate | FloatAction | Представляет виджет ползунка с указанными минимальными, максимальными значениями и значениями шага. Когда пользователь взаимодействует с ползунком, отправьте новый объект FloatAction обратно в приложение с обновленным значением. |
ToggleRangeTemplate | BooleanAction , FloatAction | Этот шаблон представляет собой комбинацию ToggleTemplate и RangeTemplate . Он поддерживает сенсорные события, а также ползунок, например, для управления регулируемой яркостью освещения. |
TemperatureControlTemplate | ModeAction , BooleanAction , FloatAction | Помимо инкапсуляции предыдущих действий, этот шаблон позволяет пользователю установить режим, например обогрев, охлаждение, обогрев/охлаждение, эко или выключение. |
StatelessTemplate | CommandAction | Используется для обозначения элемента управления, который обеспечивает сенсорное управление, но состояние которого невозможно определить, например пульта дистанционного управления ИК-телевизором. Вы можете использовать этот шаблон для определения процедуры или макроса, который представляет собой совокупность элементов управления и изменений состояния. |
Используя эту информацию, вы можете создать элемент управления:
- Используйте класс построителя
Control.StatelessBuilder
, если состояние элемента управления неизвестно. - Используйте класс построителя
Control.StatefulBuilder
, если известно состояние элемента управления.
Например, чтобы управлять умной лампочкой и термостатом, добавьте в MyCustomControlService
следующие константы:
private const val LIGHT_ID = 1234
private const val LIGHT_TITLE = "My fancy light"
private const val LIGHT_TYPE = DeviceTypes.TYPE_LIGHT
private const val THERMOSTAT_ID = 5678
private const val THERMOSTAT_TITLE = "My fancy thermostat"
private const val THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT
class MyCustomControlService : ControlsProviderService() {
...
}
public class MyCustomJavaControlService extends ControlsProviderService {
private final int LIGHT_ID = 1337;
private final String LIGHT_TITLE = "My fancy light";
private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
private final int THERMOSTAT_ID = 1338;
private final String THERMOSTAT_TITLE = "My fancy thermostat";
private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
...
}
Создайте издателей для элементов управления
После создания элемента управления ему потребуется издатель. Издатель сообщает системному пользовательскому интерфейсу о существовании элемента управления. Класс ControlsProviderService
имеет два метода издателя, которые необходимо переопределить в коде приложения:
-
createPublisherForAllAvailable()
: создаетPublisher
для всех элементов управления, доступных в вашем приложении. ИспользуйтеControl.StatelessBuilder()
для создания объектовControl
для этого издателя. -
createPublisherFor()
: создаетPublisher
для списка заданных элементов управления, определяемых их строковыми идентификаторами. ИспользуйтеControl.StatefulBuilder
для создания этих объектовControl
, поскольку издатель должен назначить состояние каждому элементу управления.
Создать издателя
Когда ваше приложение впервые публикует элементы управления в системном пользовательском интерфейсе, оно не знает состояния каждого элемента управления. Получение состояния может оказаться трудоемкой операцией, включающей множество переходов в сети поставщика устройства. Используйте метод createPublisherForAllAvailable()
чтобы объявить системе доступные элементы управления. Этот метод использует класс построителя Control.StatelessBuilder
, поскольку состояние каждого элемента управления неизвестно.
Как только элементы управления появятся в пользовательском интерфейсе Android, пользователь сможет выбрать избранные элементы управления.
Чтобы использовать сопрограммы Kotlin для создания ControlsProviderService
, добавьте новую зависимость в свой build.gradle
:
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4")
}
После синхронизации файлов Gradle добавьте в свою Service
следующий фрагмент, чтобы реализовать createPublisherForAllAvailable()
:
class MyCustomControlService : ControlsProviderService() {
override fun createPublisherForAllAvailable(): Flow.Publisher
public class MyCustomJavaControlService extends ControlsProviderService {
private final int LIGHT_ID = 1337;
private final String LIGHT_TITLE = "My fancy light";
private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
private final int THERMOSTAT_ID = 1338;
private final String THERMOSTAT_TITLE = "My fancy thermostat";
private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
private boolean toggleState = false;
private float rangeState = 18f;
private final Map
Проведите вниз по системному меню и найдите кнопку «Управление устройством» , показанную на рис. 4:

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

Теперь реализуйте метод createPublisherFor()
, добавив в свой Service
следующее:
private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job)
private val controlFlows = mutableMapOf
@NonNull
@Override
public Flow.Publisher
В этом примере метод createPublisherFor()
содержит фиктивную реализацию того, что должно делать ваше приложение: связываться с вашим устройством, чтобы получить его статус, и отправлять этот статус в систему.
Метод createPublisherFor()
использует сопрограммы и потоки Kotlin для удовлетворения требований API Reactive Streams, выполняя следующие действия:
- Создает
Flow
. - Ждет одну секунду.
- Создает и излучает состояние интеллектуального света.
- Ждет еще секунду.
- Создает и передает состояние термостата.
Обработка действий
Метод performControlAction()
сигнализирует, когда пользователь взаимодействует с опубликованным элементом управления. Тип отправленного ControlAction
определяет действие. Выполните соответствующее действие для данного элемента управления, а затем обновите состояние устройства в пользовательском интерфейсе Android.
Чтобы завершить пример, добавьте в свой Service
следующее:
override fun performControlAction(
controlId: String,
action: ControlAction,
consumer: Consumer
@Override
public void performControlAction(@NonNull String controlId, @NonNull ControlAction action, @NonNull Consumer
Запустите приложение, получите доступ к меню управления устройством и просмотрите элементы управления освещением и термостатом.
