Os apps de provedores de dados expõem informações para complicações do mostrador do relógio, disponibilizando campos que contêm texto, strings, imagens e números.
Um serviço de provedor de dados estende o
ComplicationProviderService
para disponibilizar informações
úteis diretamente para o mostrador do relógio.
Criar um projeto de provedor de dados
Para criar um projeto no Android Studio para seu app de provedor de dados, siga estas etapas:
- Clique em Studio > New > New project.
- Na janela Project Template, clique na guia "Wear OS", selecione No Activity e clique em Next.
- Na janela Configure Your Project, insira um nome, preencha as informações padrão do projeto e clique em Finish.
- O Android Studio cria um projeto com um módulo do app para o provedor de dados. Para ver mais informações sobre projetos no Android Studio, consulte Criar um projeto.
- Inicie o app de provedor de dados criando uma nova classe que estenda
BroadcastReceiver
. O objetivo dessa classe é ouvir solicitações de atualização de complementos do sistema Wear OS. Além disso, crie uma nova classe que estenda oComplicationProviderService
para fornecer dados conforme solicitado pelas complicações apropriadas. Para mais informações, consulte os recursos abaixo:- Implementar um método para solicitar atualizações
- As classes
ComplicationTapBroadcastReceiver
eCustomComplicationProviderService
neste codelab: Como expor dados a complicações de mostradores de relógio no Wear OS ComplicationToggleReceiver
,LongTextProviderService
e outras classes no exemplo de pacote de testes (em inglês
Observação: adicionar uma atividade ao provedor de dados é opcional. Por exemplo, talvez você queira que uma atividade seja iniciada apenas quando o usuário tocar em uma complicação.
Implementar um método para solicitar atualizações
Quando dados de complicação são necessários, o sistema Wear OS envia solicitações de atualização ao provedor de
dados. As solicitações são recebidas pelo
BroadcastReceiver
. Para responder às solicitações de atualização,
o provedor de dados precisa implementar o método
onComplicationUpdate()
da classe
ComplicationProviderService
.
O sistema Wear OS chama onComplicationUpdate()
quando precisa de dados do
provedor. Por exemplo, quando uma complicação que usa seu provedor se torna
ativa ou depois de passar uma quantidade fixa de tempo.
Ela transmite um objeto
ComplicationManager
como um parâmetro ao elemento
onComplicationUpdate
, que é usado para enviar dados ao sistema.
Observação: quando o app de provedor disponibiliza dados, o mostrador do relógio recebe os valores brutos enviados para mostrar as informações.
O snippet de código abaixo mostra um exemplo de implementação do
método onComplicationUpdate
:
Kotlin
override fun onComplicationUpdate( complicationId: Int, dataType: Int, complicationManager: ComplicationManager) { Log.d(TAG, "onComplicationUpdate() id: $complicationId") // Used to create a unique key to use with SharedPreferences for this complication. val thisProvider = ComponentName(this, javaClass) // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs. val preferences = getSharedPreferences(ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0) val number = preferences.getInt( ComplicationTapBroadcastReceiver.getPreferenceKey( thisProvider, complicationId), 0) val numberText = String.format(Locale.getDefault(), "%d!", number) var complicationData: ComplicationData? = null when (dataType) { ComplicationData.TYPE_SHORT_TEXT -> complicationData = ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(numberText)) .build() else -> if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unexpected complication type $dataType") } } if (complicationData != null) { complicationManager.updateComplicationData(complicationId, complicationData) } else { // If no data is sent, we still need to inform the ComplicationManager, so // the update job can finish and the wake lock isn't held any longer. complicationManager.noUpdateRequired(complicationId) } }
Java
@Override public void onComplicationUpdate( int complicationId, int dataType, ComplicationManager complicationManager) { Log.d(TAG, "onComplicationUpdate() id: " + complicationId); // Used to create a unique key to use with SharedPreferences for this complication. ComponentName thisProvider = new ComponentName(this, getClass()); // Retrieves your data; in this case, grabs an incrementing number from SharedPrefs. SharedPreferences preferences = getSharedPreferences( ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0); int number = preferences.getInt( ComplicationTapBroadcastReceiver.getPreferenceKey( thisProvider, complicationId), 0); String numberText = String.format(Locale.getDefault(), "%d!", number); ComplicationData complicationData = null; switch (dataType) { case ComplicationData.TYPE_SHORT_TEXT: complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT) .setShortText(ComplicationText.plainText(numberText)) .build(); break; default: if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Unexpected complication type " + dataType); } } if (complicationData != null) { complicationManager.updateComplicationData(complicationId, complicationData); } else { // If no data is sent, we still need to inform the ComplicationManager, so // the update job can finish and the wake lock isn't held any longer. complicationManager.noUpdateRequired(complicationId); } }
Declarações e permissões do manifesto
Um app de provedor de dados precisa incluir declarações específicas no manifesto para ser tratado como provedor de dados pelo sistema Android. Esta seção explica as configurações necessárias para um app de provedor de dados.
No manifesto do app, declare o serviço e adicione um filtro de intent da ação de solicitação de atualização.
O manifesto também precisa proteger o serviço, adicionando a permissão BIND_COMPLICATION_PROVIDER
para garantir que apenas o sistema Wear OS se vincule aos serviços do provedor.
Além disso, inclua um atributo android:icon
no
elemento service
que forneça um
ícone branco. Recomendamos drawables vetoriais para os ícones.
O ícone representa o provedor e é mostrado no seletor de
provedores.
Confira um exemplo:
<service android:name=".provider.IncrementingNumberComplicationProviderService" android:icon="@drawable/icn_complications" android:label="@string/complications_provider_incrementing_number" android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER"> <intent-filter> <action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/> </intent-filter> </service>
Especificar os elementos de metadados
No arquivo de manifesto, inclua metadados para especificar os tipos com suporte, o período de atualização e a ação de configuração, conforme mostrado no exemplo a seguir:
<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES" android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT" /> <meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="300" />
Quando o provedor de dados de complicação está ativo,
UPDATE_PERIOD_SECONDS
especifica a frequência com que você quer que
o sistema verifique se há atualizações para os dados. Caso não seja necessário atualizar as informações
mostradas na complicação regularmente, como
ao usar atualizações push, defina esse valor como
0
.
Se você não definir UPDATE_PERIOD_SECONDS
como 0
,
será necessário usar um valor de pelo menos 300
(cinco minutos), que é
o período mínimo de atualização que o sistema impõe, para preservar
a duração da bateria do dispositivo. Além disso, as solicitações de atualização
ocorrem com menos frequência quando o dispositivo está no modo ambiente ou não está sendo usado.
Para mais detalhes sobre o envio de atualizações, consulte as chaves listadas para a classe
ComplicationProviderService
na
Referência da API
do Wear.
Adicionar uma atividade de configuração
Se necessário, um provedor pode incluir uma atividade de configuração, que é mostrada quando o usuário seleciona um provedor de dados. Para incluir a atividade de configuração, inclua um item de metadados na declaração do serviço de provedor no manifesto com esta chave:
<meta-data android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION" android:value="PROVIDER_CONFIG_ACTION"/>
O valor pode ser qualquer ação.
Em seguida, crie a atividade de configuração com um filtro de intent para essa
ação. A atividade de configuração precisa ficar no mesmo pacote que o
provedor. A atividade de configuração precisa retornar RESULT_OK
ou
RESULT_CANCELED
para informar ao sistema se o provedor
será definido.
Mostradores de relógio seguros especificados pelo provedor
Os provedores podem especificar alguns mostradores do relógio como "seguros" para receber dados. Essa função só é usada quando um mostrador de relógio tenta usar o provedor como padrão e o provedor confia no app do mostrador.
Para declarar que os mostradores de relógio são seguros, o provedor adiciona metadados com uma chave de
android.support.wearable.complications.SAFE_WATCH_FACES
. O
valor dos metadados é uma lista separada por vírgulas de nomes de componentes
WatchFaceService
, fornecidos como se
ComponentName.flattenToString()
tivesse sido chamado, ou
nomes de pacotes do app. Nesse caso todos os mostradores do relógio em um
app especificado são considerados seguros. O espaço em branco na lista de valores é ignorado. Exemplo:
<meta-data android:name="android.support.wearable.complications.SAFE_WATCH_FACES" android:value=" com.app.watchface/com.app.watchface.MyWatchFaceService, com.anotherapp.anotherwatchface/com.something.WatchFaceService, com.something.text"/>
Usar imagens com proteção de pixels
Evite usar blocos sólidos de cor no modo ambiente em telas suscetíveis a burn-in. Se os ícones ou as imagens incluírem blocos sólidos de cor, forneça também uma versão com proteção contra burn-in.
Ao disponibilizar um ícone usando
ComplicationData.Builder#setIcon
, inclua uma versão com proteção contra burn-in,
com
ComplicationData.Builder#setBurnInProtectionIcon
.
Ao disponibilizar uma imagem usando
ComplicationData.Builder#setSmallImage
, inclua uma versão com proteção contra burn-in,
com
ComplicationData.Builder#setBurnInProtectionSmallImage
.
Usar atualizações push
Em vez de especificar um intervalo de atualizações diferente de zero para uma
complicação no manifesto do app, é possível usar uma instância de
ComplicationDataSourceUpdateRequester
para solicitar atualizações de forma dinâmica.
Para solicitar uma atualização do conteúdo visível ao usuário da complicação, chame
requestUpdate()
.
Cuidado: para preservar a duração da bateria do dispositivo,
não chame o método requestUpdate()
da instância do
ComplicationDataSourceUpdateRequester
com frequência maior do que a cada cinco
minutos, em média.
Fornecer valores dinâmicos
A partir do Wear OS 4, algumas complicações podem mostrar valores atualizados com mais frequência
com base nos valores disponíveis diretamente para a plataforma. Para oferecer essa capacidade
suas complicações, use
ComplicationData
que aceitam
valores dinâmicos. A plataforma avalia e
atualiza esses valores com frequência, sem exigir que o provedor de complicações esteja em execução.
Exemplos de campos incluem
campo de valor dinâmico de GoalProgressComplicationData
DynamicComplicationText
, que pode ser usado em qualquer
ComplicationText
. Esses valores dinâmicos são baseados
androidx.wear.protolayout.expression
.
Em determinadas situações, a plataforma não pode avaliar valores dinâmicos:
- O valor dinâmico às vezes não está disponível : isso acontece, por exemplo, quando o
dispositivo está fora do pulso. Nessas situações, a plataforma usa o valor
da
campo substituto de invalidação de valor dinâmico, em um
Campo de marcador de posição de
NoDataComplicationData
. - O valor dinâmico nunca está disponível : isso acontece em um dispositivo que está sendo executado em um
versão mais antiga do Wear OS 4. Nessa situação, a plataforma usa um campo
substituto complementar,
como
getFallbackValue()
:
Fornecer valores que dependem do horário
Algumas complicações precisam exibir um valor que é associado ao horário atual. Alguns exemplos são a data atual, o tempo restante até a próxima reunião ou a hora em um fuso horário diferente.
Não atualize uma complicação a cada
segundo ou minuto. Em vez disso,
especifique os valores como relativos à data ou ao horário, usando um texto dependente de horário.
Use builders na classe ComplicationText
para criar esses valores que dependem do horário.
Taxa de atualização de complementos
É possível atualizar as complicações com bastante frequência. No entanto, isso pode afetar a duração da bateria do dispositivo. Você pode usar uma API de solicitação de complementos privilegiada que permite que complementos específicas sejam atualizadas com mais frequência. No entanto, o uso dessa API precisa ser permitido pelo fabricante do smartwatch. Cada fabricante decide quais complicações podem ser atualizadas com uma frequência mais rápida do que o permitido normalmente.
Recursos relacionados
- Repositório de exemplos do Wear OS (em inglês)