Быстрые настройки – это плитки, которые показываются на панели быстрых настроек и представляют собой действия, которые пользователи могут выполнять, чтобы быстро решать повторяющиеся задачи.
Ваше приложение может предоставлять пользователям специальную плитку с помощью класса 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 категории используются в быстрых настройках, производители могут как использовать, так и игнорировать эту информацию в своих системных интерфейсах.
Предложить пользователю добавить вашу плитку
Чтобы добавить плитку вручную, пользователям нужно выполнить несколько действий:
- Откройте панель быстрых настроек, проведя по экрану сверху вниз.
- Нажмите кнопку "Изменить".
- Прокрутите все карточки на устройстве, пока не найдете свою.
- Нажмите на карточку и удерживайте ее, а затем перетащите в список активных карточек.
Пользователь также может в любой момент переместить или удалить ваш виджет.
На устройствах с Android 13 и более поздних версий вы можете использовать метод requestAddTileService(), чтобы пользователям было проще добавлять ваш элемент на устройство. Этот метод позволяет быстро добавить ваш параметр на панель быстрых настроек. В запросе будут указаны название приложения, предоставленный ярлык и значок.
public void requestAddTileService (
ComponentName tileServiceComponentName,
CharSequence tileLabel,
Icon icon,
Executor resultExecutor,
Consumer<Integer> resultCallback
)
Обратный вызов содержит информацию о том, был ли добавлен элемент, не был добавлен, уже был добавлен или возникла ошибка.
Используйте свое усмотрение при принятии решения о том, когда и как часто показывать пользователям запросы. Мы рекомендуем вызывать requestAddTileService() только в контексте, например когда пользователь впервые взаимодействует с функцией, которую поддерживает ваш значок.
Система может перестать обрабатывать запросы для определенного ComponentName, если пользователь отклонял их достаточное количество раз. Пользователь определяется по файлу cookie Context, который используется для получения этого сервиса. Он должен совпадать с текущим пользователем.