Criar um host de widgets

A tela inicial do Android, disponível na maioria dos dispositivos com Android, permite que widgets de aplicativos (ou widgets) a incorporar por usuários acesso rápido ao conteúdo. Se você estiver criando uma tela inicial substituta ou um app semelhante, também é possível permitir que o usuário incorpore widgets implementando AppWidgetHost. Não está algo que a maioria dos aplicativos precisa fazer, mas se você estiver criando seu próprio host, ele será é importante entender as obrigações contratuais com as quais o host concorda implicitamente.

Esta página se concentra nas responsabilidades envolvidas na implementação de um AppWidgetHost personalizado. Para conferir um exemplo específico de como implementar um AppWidgetHost, consulte o código-fonte da LauncherAppWidgetHost da tela inicial do Android.

Aqui está uma visão geral dos principais conceitos e classes envolvidos na implementação de um AppWidgetHost personalizado:

  • Host do widget do app: o AppWidgetHost fornece a interação com o Serviço AppWidget para apps que incorporam widgets na interface. Um AppWidgetHost precisa ter um ID exclusivo no pacote do host. O ID persiste em todos os usos do host. O ID geralmente é um valor codificado que você atribui no app.

  • ID do widget de app: cada instância de widget recebe um ID exclusivo no momento de encadernação. Consulte bindAppWidgetIdIfAllowed() Para mais detalhes, confira a seção Vincular widgets a seguir. O recebe o ID exclusivo usando allocateAppWidgetId() Esse ID persiste durante toda a vida útil do widget até ser excluído do host. Qualquer estado específico do host, como o tamanho e o local do widget—deve ser mantido pelo pacote de hospedagem e associado ao ID do widget de app.

  • Visualização do host de widgets de apps: pense no AppWidgetHostView como um frame em que o widget é agrupado sempre que precisa ser exibido. Um widget é associado a um AppWidgetHostView sempre que é inflado pelo host.

    • Por padrão, o sistema cria um AppWidgetHostView, mas o host pode criar a própria subclasse de AppWidgetHostView estendendo-a.
    • A partir do Android 12 (nível 31 da API), a AppWidgetHostView apresenta a as setColorResources() e resetColorResources() métodos para lidar com cores dinamicamente sobrecarregadas. O host é responsável por fornecer as cores para esses métodos.
  • Pacote de opções: o AppWidgetHost usa o pacote de opções para comunicar informações ao AppWidgetProvider sobre como o widget é exibido, por exemplo, a lista de faixas de tamanho e se o widget está em uma tela de bloqueio ou na tela inicial. Com essas informações, AppWidgetProvider personalizam o conteúdo e a aparência do widget com base em como e onde ele é exibido. Você pode usar updateAppWidgetOptions() e updateAppWidgetSize() para modificar o pacote de um widget. Esses dois métodos acionam o callback onAppWidgetOptionsChanged() para o AppWidgetProvider.

Vincular widgets

Quando um usuário adiciona um widget a um host, ocorre um processo chamado vinculação. Vinculação refere-se à associação de um determinado ID de widget de aplicativo a um host específico e um AppWidgetProvider específica.

As APIs de vinculação também permitem que um host forneça uma IU personalizada para vinculação. Para usar esse processo, o app precisa declarar a BIND_APPWIDGET no manifesto do host:

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

No entanto, esse é apenas o primeiro passo. No momento da execução, o usuário precisa conceder explicitamente a permissão para o app adicionar um widget ao host. Para testar se o app tem permissão para adicionar o widget, use o método bindAppWidgetIdIfAllowed(). Se bindAppWidgetIdIfAllowed() retornar false, o app precisará exibir uma caixa de diálogo solicitando que o usuário conceda a permissão: "allow" para o widget atual adição ou "sempre permitir" para cobrir todas as futuras adições de widgets.

Este snippet demonstra um exemplo de como exibir a caixa de diálogo:

Kotlin

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);

O host precisa verificar se o widget adicionado por um usuário precisa de configuração. Para mais informações, consulte Permitir que os usuários configurem apps widgets.

Responsabilidades do host

É possível especificar diversas configurações para widgets usando os metadados AppWidgetProviderInfo. É possível recuperar essas opções de configuração, abordadas com mais detalhes nas próximas seções, do objeto AppWidgetProviderInfo associado a um provedor de widgets.

Independentemente da versão do Android que você está segmentando, todos os hosts têm a seguintes responsabilidades:

  • Ao adicionar um widget, aloque o ID do widget conforme descrito anteriormente. Quando um for removido do host, chame deleteAppWidgetId() para desalocar o ID do widget.

  • Ao adicionar um widget, verifique se a atividade de configuração precisa ser iniciada. Normalmente, o host precisa iniciar a configuração do widget atividade, se ela existir e não estiver marcada como opcional especificando os dois Sinalizações configuration_optional e reconfigurable. Consulte Atualizar o widget pela atividade de configuração para mais detalhes. Essa é uma etapa necessária para muitos widgets antes que eles possam ser mostrados.

  • Os widgets especificam uma largura e altura padrão nos metadados AppWidgetProviderInfo. Esses valores são definidos em células, começando em Android 12, se targetCellWidth e targetCellHeight forem especificado, ou dps, se apenas minWidth e minHeight forem especificados. Consulte Atributos de dimensionamento de widgets.

    Verifique se o widget está disposto com pelo menos essa quantidade de dps. Por exemplo, muitos hosts alinham ícones e widgets em uma grade. Nesse cenário, Por padrão, o host adiciona um widget usando o número mínimo de células que atendem às restrições de minWidth e minHeight.

Além dos requisitos listados na seção anterior, versões específicas da plataforma introduzem recursos que colocam novas responsabilidades no host.

Determine sua abordagem com base na versão do Android de destino

Android 12

O Android 12 (nível 31 da API) agrupa um List<SizeF> extra que contém a lista de tamanhos possíveis em dps que uma instância de widget pode usar no pacote de opções. O número de tamanhos fornecidos depende da implementação do host. Os hosts normalmente oferecem dois tamanhos para smartphones (retrato e paisagem) e quatro tamanhos para dispositivos dobráveis.

Há um limite de MAX_INIT_VIEW_COUNT (16) para o número de RemoteViews que um AppWidgetProvider pode fornecer para RemoteViews Como os objetos AppWidgetProvider mapeiam um objeto RemoteViews para cada tamanho na List<SizeF>, não forneça mais de MAX_INIT_VIEW_COUNT tamanhos.

O Android 12 também apresenta a maxResizeWidth e maxResizeHeight atributos em dps. Recomendamos que um widget que use pelo menos um desses atributos não exceda o tamanho especificado pelos atributos.

Outros recursos

  • Consulte a documentação de referência de Glance.