Создайте хост виджетов

Главный экран Android, доступный на большинстве устройств на базе Android, позволяет пользователю встраивать виджеты приложений (или виджеты ) для быстрого доступа к контенту. Если вы разрабатываете замену главному экрану или аналогичное приложение, вы также можете разрешить пользователю встраивать виджеты, реализовав AppWidgetHost . Большинству приложений это не требуется, но если вы создаете собственный хост, важно понимать договорные обязательства, которые неявно принимает хост.

На этой странице рассматриваются обязанности, связанные с реализацией пользовательского AppWidgetHost . Конкретный пример реализации AppWidgetHost можно найти в исходном коде главного экрана Android LauncherAppWidgetHost .

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

  • Хост виджетов приложений : AppWidgetHost обеспечивает взаимодействие со службой AppWidget для приложений, встраивающих виджеты в свой пользовательский интерфейс. AppWidgetHost должен иметь уникальный идентификатор в пределах пакета хоста. Этот идентификатор сохраняется при каждом использовании хоста. Обычно идентификатор — это жёстко заданное значение, которое вы назначаете в своём приложении.

  • ID виджета приложения : каждому экземпляру виджета присваивается уникальный идентификатор во время привязки. См. bindAppWidgetIdIfAllowed() и, для получения более подробной информации, раздел « Привязка виджетов» ниже. Хост получает уникальный идентификатор с помощью allocateAppWidgetId() . Этот идентификатор сохраняется на протяжении всего жизненного цикла виджета до его удаления с хоста. Любое состояние, специфичное для хоста, например, размер и расположение виджета, должно сохраняться пакетом хостинга и связываться с идентификатором виджета приложения.

  • Вид хоста виджета приложения : представьте AppWidgetHostView как фрейм, в который обёртывается виджет при необходимости его отображения. Виджет связывается с AppWidgetHostView каждый раз, когда он заполняется хостом.

    • По умолчанию система создает AppWidgetHostView , но хост может создать свой собственный подкласс AppWidgetHostView , расширив его.
    • Начиная с Android 12 (уровень API 31), AppWidgetHostView представляет методы setColorResources() и resetColorResources() для обработки динамически перегруженных цветов. Хост отвечает за предоставление цветов этим методам.
  • Пакет параметров : AppWidgetHost использует пакет параметров для передачи AppWidgetProvider информации о том, как отображается виджет, например, список диапазонов размеров , и о том, находится ли виджет на экране блокировки или на главном экране. Эта информация позволяет AppWidgetProvider настраивать содержимое и внешний вид виджета в зависимости от того, как и где он отображается. Для изменения пакета виджета можно использовать updateAppWidgetOptions() и updateAppWidgetSize() . Оба этих метода запускают обратный вызов onAppWidgetOptionsChanged() к AppWidgetProvider .

Привязка виджетов

Когда пользователь добавляет виджет на хост, происходит процесс, называемый привязкой . Привязка подразумевает связывание конкретного идентификатора виджета приложения с конкретным хостом и конкретным AppWidgetProvider .

API привязки также позволяют хосту предоставлять собственный пользовательский интерфейс для привязки. Чтобы использовать этот процесс, ваше приложение должно объявить разрешение BIND_APPWIDGET в манифесте хоста:

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

Но это только первый шаг. Во время выполнения пользователь должен явно предоставить вашему приложению разрешение на добавление виджета на хост. Чтобы проверить, есть ли у вашего приложения разрешение на добавление виджета, используйте метод bindAppWidgetIdIfAllowed() . Если bindAppWidgetIdIfAllowed() возвращает false , ваше приложение должно отобразить диалоговое окно с предложением предоставить разрешение: «разрешить» для текущего добавления виджета или «всегда разрешать» для всех будущих добавлений виджетов.

В этом фрагменте показан пример отображения диалогового окна:

Котлин

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Ява

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

Хост должен проверить, требуется ли настройка виджета, добавляемого пользователем. Подробнее см. в разделе «Разрешить пользователям настраивать виджеты приложений» .

Обязанности хозяина

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

Независимо от того, на какую версию Android вы ориентируетесь, все хосты имеют следующие обязанности:

  • При добавлении виджета выделите его идентификатор, как описано ранее. При удалении виджета с хоста вызовите метод deleteAppWidgetId() чтобы освободить идентификатор виджета.

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

  • Ширина и высота виджетов по умолчанию задаются в метаданных AppWidgetProviderInfo . Эти значения определяются в ячейках (начиная с Android 12, если указаны targetCellWidth и targetCellHeight , или в dps, если указаны только minWidth и minHeight . См. раздел Атрибуты размера виджета .

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

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

Определите свой подход на основе целевой версии Android.

Андроид 12

В Android 12 (уровень API 31) в пакете параметров добавлен дополнительный List<SizeF> , содержащий список возможных размеров виджета в dps. Количество доступных размеров зависит от реализации хоста. Хост обычно предоставляет два размера для телефонов — книжный и альбомный — и четыре размера для складных устройств.

Количество различных RemoteViews , которые AppWidgetProvider может предоставить для RemoteViews , ограничено MAX_INIT_VIEW_COUNT (16). Поскольку объекты AppWidgetProvider сопоставляют объект RemoteViews с каждым размером из List<SizeF> , не предоставляйте больше MAX_INIT_VIEW_COUNT размеров.

В Android 12 также появились атрибуты maxResizeWidth и maxResizeHeight в dps. Мы рекомендуем, чтобы виджет, использующий хотя бы один из этих атрибутов, не превышал размер, указанный в этих атрибутах.

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

  • См. справочную документацию Glance .