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

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

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

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

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

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

  • AppWidgetHostView 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)

Java

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 . См. Атрибуты размера виджета .

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

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

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

Android 12

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

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

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

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

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