Быстрые настройки – это карточки на панели быстрых настроек, которые представляют собой действия. Нажав на карточку, пользователь может быстро выполнить повторяющуюся задачу.
Приложение может предоставлять пользователям настраиваемую карточку через класс TileService и использовать объект Tile для отслеживания состояния карточки. Например, вы можете создать элемент, который позволяет пользователям включать или выключать VPN, предоставляемый вашим приложением.
Когда создавать карточку
Рекомендуем создавать карточки для функций, которые пользователи часто используют или к которым им нужен быстрый доступ. Наиболее эффективные карточки сочетают в себе оба этих качества, обеспечивая быстрый доступ к часто выполняемым действиям.
Например, вы можете создать карточку для фитнес-приложения, которая позволит пользователям быстро начать тренировку. Однако мы не рекомендуем создавать карточку для того же приложения, которая позволит пользователям просматривать всю историю тренировок.
Чтобы карточку было проще найти и использовать, рекомендуем избегать следующих практик:
Не используйте карточки для запуска приложений. Вместо этого используйте ярлык приложения или стандартный лаунчер.
Не используйте карточки для однократных действий пользователя. Используйте ярлык приложения или уведомление.
Не создавайте слишком много карточек. Рекомендуем использовать не более двух ярлыков для каждого приложения.
Не используйте карточки, которые только показывают информацию, но не позволяют пользователям взаимодействовать с ней. Используйте уведомление или виджет.
Создайте карточку
Чтобы создать карточку, сначала создайте подходящий значок, а затем создайте и объявите TileService в файле манифеста приложения.
Пример создания и управления карточкой можно найти в образце быстрых настроек.
Создайте собственный значок
Вам нужно будет предоставить собственный значок, который будет показываться на карточке на панели быстрых настроек. (Вы добавите этот значок при объявлении TileService, как описано в следующем разделе.) Значок должен быть белым, с прозрачным фоном, размером 24 x 24 dp и в формате VectorDrawable.
Создайте значок, который визуально намекает на назначение карточки. Это помогает пользователям понять, подходит ли им ваша карточка. Например, для карточки фитнес-приложения, которая позволяет начать тренировку, можно создать значок секундомера.
Как создать и объявить TileService
Создайте сервис для карточки, расширяющий класс TileService.
class MyQSTileService : TileService() { // Called when the user adds your tile. override fun onTileAdded() { super.onTileAdded() } // Called when your app can update your tile. override fun onStartListening() { super.onStartListening() } // Called when your app can no longer update your tile. override fun onStopListening() { super.onStopListening() } // Called when the user taps on your tile in an active or inactive state. override fun onClick() { super.onClick() } // Called when the user removes your tile. override fun onTileRemoved() { super.onTileRemoved() } }
Объявите TileService в файле манифеста приложения. Добавьте название и ярлык для TileService (не более 18 символов для android:label), собственный значок, созданный в предыдущем разделе, и соответствующее разрешение.
<!-- 18-character limit for android:label. -->
<service
android:name=".MyQSTileService"
android:exported="true"
android:label="@string/my_default_tile_label"
android:icon="@drawable/my_default_icon_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
Как управлять TileService
После того как вы создали и объявили TileService в манифесте приложения, вам нужно управлять его состоянием.
TileService – это привязанная служба. Привязка TileService выполняется по запросу приложения или когда системе нужно связаться с ним. Типичный жизненный цикл привязанной службы содержит следующие четыре метода обратного вызова: onCreate(), onBind(), onUnbind() и onDestroy(). Эти методы вызываются системой каждый раз, когда сервис переходит на новый этап жизненного цикла.
Обзор жизненного цикла TileService
Помимо обратных вызовов, управляющих жизненным циклом привязанной службы, необходимо реализовать другие методы, относящиеся к жизненному циклу TileService. Эти методы могут вызываться за пределами onCreate() и onDestroy(), поскольку методы жизненного цикла Service и TileService вызываются в двух отдельных асинхронных потоках.
Жизненный цикл TileService содержит следующие методы, которые вызываются системой каждый раз, когда TileService переходит на новый этап жизненного цикла:
onTileAdded(). Этот метод вызывается, только когда пользователь добавляет карточку в первый раз или удаляет и снова добавляет ее. Это лучшее время для выполнения любой однократной инициализации. Однако этого может быть недостаточно для инициализации.onStartListening()иonStopListening(). Эти методы вызываются каждый раз, когда приложение обновляет карточку. Это происходит часто.TileServiceостается связанным сonStartListening()иonStopListening(), что позволяет приложению изменять карточку и отправлять обновления.onTileRemoved()– этот метод вызывается, только если пользователь удаляет вашу карточку.
Выберите режим прослушивания
TileService может слушать в активном или неактивном режиме. Рекомендуем использовать активный режим, который нужно объявить в манифесте приложения.
В противном случае TileService – это стандартный режим, и его не нужно объявлять.
Не думайте, что TileService будет существовать вне пары методов onStartListening() и onStopListening().
Активный режим (рекомендуется)
Используйте активный режим для TileService, который прослушивает и отслеживает свое состояние в собственном процессе. TileService в активном режиме привязывается к onTileAdded(), onTileRemoved(), событиям нажатия и когда этого требует процесс приложения.
Рекомендуем использовать активный режим, если TileService получает уведомление, когда состояние карточки должно быть обновлено собственным процессом. Активные элементы снижают нагрузку на систему, поскольку их не нужно привязывать каждый раз, когда пользователь открывает панель быстрых настроек.
Статический метод TileService.requestListeningState() можно вызвать, чтобы запросить запуск состояния прослушивания и получить обратный вызов для onStartListening().
Чтобы объявить активный режим, добавьте в файл манифеста приложения строку META_DATA_ACTIVE_TILE.
<service ...>
<meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
...
</service>
Неактивный режим
Неактивный режим – это стандартный режим. TileService находится в неактивном режиме, если он привязан, когда карточка видна пользователю. Это означает, что ваш TileService может быть создан и привязан снова в моменты, которые он не контролирует. Она также может быть отвязана и удалена, когда пользователь не просматривает карточку.
После того как пользователь откроет панель быстрых настроек, приложение получит обратный вызов onStartListening(). Вы можете обновлять объект Tile сколько угодно раз в период между onStartListening() и onStopListening().
Неактивный режим объявлять не нужно. Не добавляйте в файл манифеста приложения разрешение META_DATA_ACTIVE_TILE.
Обзор состояний карточек
После того как пользователь добавит вашу карточку, она всегда будет находиться в одном из следующих состояний.
STATE_ACTIVE– указывает, что функция включена. В этом состоянии пользователь может взаимодействовать с карточкой.Например, для карточки фитнес-приложения, которая позволяет пользователям начать тренировку с таймером,
STATE_ACTIVEбудет означать, что пользователь начал тренировку и таймер запущен.STATE_INACTIVE– указывает на то, что функция отключена или приостановлена. В этом состоянии пользователь может взаимодействовать с карточкой.Вернемся к примеру с карточкой фитнес-приложения. Если она находится в состоянии
STATE_INACTIVE, это значит, что пользователь не начал тренировку, но может сделать это в любой момент.STATE_UNAVAILABLE– указывает на временную недоступность. Пользователь не может взаимодействовать с элементом в этом состоянии.Например, если карточка в
STATE_UNAVAILABLE, значит она по какой-то причине недоступна пользователю.
Система задает только начальное состояние объекта Tile. Вы задаете состояние объекта Tile на протяжении всего его жизненного цикла.
Система может изменить цвет значка и фона карточки в зависимости от состояния объекта Tile. Объекты Tile, для которых задано значение STATE_ACTIVE, будут самыми темными, а объекты STATE_INACTIVE и STATE_UNAVAILABLE – более светлыми. Точный оттенок зависит от производителя и версии.
Обновите карточку
Вы сможете обновить элемент, когда получите обратный вызов в onStartListening().
В зависимости от режима карточки она может обновляться по крайней мере один раз, пока не будет получен обратный вызов onStopListening().
В активном режиме вы можете обновить карточку ровно один раз, прежде чем получите обратный вызов onStopListening(). В неактивном режиме вы можете обновлять свой элемент сколько угодно раз с onStartListening() до onStopListening().
Чтобы получить объект Tile, вызовите getQsTile(). Чтобы обновить определенные поля объекта Tile, вызовите следующие методы:
После того как вы зададите правильные значения полей объекта Tile, вызовите метод updateTile(), чтобы обновить карточку. Это заставит систему проанализировать обновленные данные карточки и обновить пользовательский интерфейс.
data class StateModel(val enabled: Boolean, val label: String, val icon: Icon) override fun onStartListening() { super.onStartListening() val state = getStateFromService() qsTile.label = state.label qsTile.contentDescription = state.label qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.icon = state.icon qsTile.updateTile() }
Обработка нажатий
Пользователи могут нажать на карточку, чтобы запустить действие, если карточка находится в STATE_ACTIVE или STATE_INACTIVE. Затем система вызывает обратный вызов onClick() вашего приложения.
Когда приложение получит обратный вызов onClick(), оно сможет запустить диалоговое окно или действие, запустить фоновую работу или изменить состояние карточки.
var counter = 0 override fun onClick() { super.onClick() counter++ qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE qsTile.label = "Clicked $counter times" qsTile.contentDescription = qsTile.label qsTile.updateTile() }
Открыть диалоговое окно
showDialog() сворачивает панель быстрых настроек и открывает диалоговое окно.
Используйте диалоговое окно, чтобы добавить контекст к действию, если оно требует дополнительных входных данных или согласия пользователя.
Как запустить занятие
startActivityAndCollapse() начинает занятие и сворачивает панель. Действия полезны, если нужно показать больше информации, чем помещается в диалоговом окне, или если ваше действие предполагает активное взаимодействие с пользователем.
Если ваше приложение требует значительного взаимодействия с пользователем, запускайте действие только в крайнем случае. Вместо этого используйте диалоговое окно или переключатель.
При долгом нажатии на карточку открывается экран О приложении. Чтобы переопределить это поведение и вместо этого запустить действие для настройки предпочтений, добавьте <intent-filter> к одному из ваших действий с помощью ACTION_QS_TILE_PREFERENCES.
Начиная с Android API 28, в PendingIntent должен быть Intent.FLAG_ACTIVITY_NEW_TASK:
if (Build.VERSION.SDK_INT >= 28) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
Вы также можете добавить пометку в AndroidManifest.xml в разделе Activity.
Как сделать параметр переключаемым
Рекомендуем помечать карточку как переключаемую, если она в основном работает как переключатель с двумя состояниями (это наиболее распространенное поведение карточек). Это помогает предоставить информацию о поведении плитки операционной системе и улучшить общую доступность.
Чтобы сделать карточку переключаемой, задайте для метаданных TOGGLEABLE_TILE значение true.
<service ...>
<meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
Выполнять только безопасные действия на заблокированных устройствах.
Ваша карточка может показываться поверх заблокированного экрана. Если на карточке есть конфиденциальная информация, проверьте значение isSecure(), чтобы определить, находится ли устройство в безопасном состоянии, и соответствующим образом измените поведение TileService.
Если действие, связанное с элементом, можно безопасно выполнить на заблокированном экране, используйте startActivity(), чтобы запустить действие поверх заблокированного экрана.
Если действие небезопасно, используйте unlockAndRun(), чтобы попросить пользователя разблокировать устройство. В случае успеха система выполняет объект Runnable, который вы передаете в этот метод.
Как распределить карточки по категориям
Чтобы пользователям было удобнее работать с быстрыми настройками, вы можете добавить параметр в категорию. Система распределяет карточки по категориям, таким как "Подключение", "Экран" и "Конфиденциальность". Система использует эти категории для сортировки и группировки карточек в режиме редактирования быстрых настроек, чтобы пользователям было проще находить их и управлять ими.
Реализация
Чтобы указать категорию для TileService, добавьте поле метаданных в объявление сервиса в файле AndroidManifest.xml:
- В файле
AndroidManifest.xmlв элементе<service>дляTileServiceдобавьте элемент<meta-data>. android:name: задайте значениеandroid.service.quicksettings.TILE_CATEGORY.android:value– назначьте одну из предопределенных констант категорий, напримерandroid.service.quicksettings.CATEGORY_CONNECTIVITYилиandroid.service.quicksettings.CATEGORY_DISPLAY.
как показано в примере ниже:
<service
android:name=".MyConnectivityTileService"
[...]
>
<meta-data android:name="android.service.quicksettings.TILE_CATEGORY"
android:value="android.service.quicksettings.CATEGORY_CONNECTIVITY" />
</service>
API предоставляет набор предопределенных категорий на выбор. Эти категории определены как строковые константы в классе TileService.
Если категория не указана, система автоматически назначает категорию по умолчанию:
- Из системных приложений. Карточки, которые являются частью системного приложения.
- Из установленных приложений. Карточки из приложений, установленных пользователем.
Хотя устройства Google Pixel используют категории в быстрых настройках, OEM-производители могут использовать или игнорировать эту информацию о категориях в своих системных интерфейсах.
Предложите пользователю добавить карточку
Чтобы добавить карточку вручную, пользователям нужно выполнить несколько действий:
- Проведите по экрану сверху вниз, чтобы открыть панель быстрых настроек.
- Нажмите кнопку "Изменить".
- Прокрутить все карточки на устройстве, пока не найдет вашу.
- Нажмите на карточку и удерживайте ее, а затем перетащите в список активных карточек.
Пользователь также может в любой момент переместить или удалить вашу карточку.
Начиная с Android 13, вы можете использовать метод requestAddTileService(), чтобы пользователям было проще добавлять карточки на устройство. Этот метод предлагает пользователям быстро добавить ваш параметр на панель быстрых настроек. В запросе указывается название приложения, предоставленный ярлык и значок.
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
Обратный вызов содержит информацию о том, был ли добавлен элемент, не был ли он добавлен, был ли он уже там или произошла ли какая-либо ошибка.
Решите, когда и как часто вы будете предлагать пользователям оставить отзыв. Рекомендуем вызывать requestAddTileService() только в контексте, например когда пользователь впервые взаимодействует с функцией, которую поддерживает ваша карточка.
Система может прекратить обработку запросов на предоставление определенного разрешения ComponentName, если пользователь отклонил его достаточное количество раз. Пользователь определяется по Context, используемому для получения этого сервиса. Он должен совпадать с текущим пользователем.