As fontes de dados de complicação expõem informações para complicações do mostrador do relógio, disponibilizando texto, imagens e números que o mostrador pode renderizar.
Um serviço de fonte de dados estende o
SuspendingComplicationDataSourceService para disponibilizar informações
úteis diretamente para o mostrador do relógio.
Primeiros passos
Adicione a seguinte dependência ao módulo do app:
dependencies { implementiation("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1") }
Criar o serviço de fonte de dados
Quando dados de complicação são necessários, o sistema Wear OS envia solicitações de atualização à fonte de dados.
Para responder às solicitações de atualização, a fonte de dados precisa implementar o método
onComplicationRequest() da classe
SuspendingComplicationDataSourceService.
O sistema Wear OS chama onComplicationRequest() quando precisa de dados da
fonte. Por exemplo, quando uma complicação que usa sua fonte de dados se torna ativa ou depois de
passar uma quantidade fixa de tempo.
Observação:quando a fonte de dados disponibiliza dados, o mostrador do relógio recebe os valores brutos. O mostrador do relógio é responsável por formatar os dados para exibição.
O snippet de código abaixo mostra um exemplo de implementação:
class MyComplicationDataSourceService : SuspendingComplicationDataSourceService() { override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationData? { // Retrieve the latest info for inclusion in the data. val text = getLatestData() return shortTextComplicationData(text) } override fun getPreviewData(type: ComplicationType): ComplicationData? { return shortTextComplicationData("Event 1") } private fun shortTextComplicationData(text: String) = ShortTextComplicationData.Builder( text = PlainComplicationText.Builder(text).build(), contentDescription = PlainComplicationText.Builder(text).build() ) // Add further optional details here such as icon, tap action, and title. .build() // ... }
Declarações e permissões do manifesto
As fontes de dados precisam incluir declarações específicas no manifesto do app para serem tratadas como fontes de dados pelo sistema Android. Esta seção explica as configurações necessárias para fontes 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 a fonte de dados e é mostrado no seletor de complicações.
Veja um exemplo:
<service android:name=".snippets.complication.MyComplicationDataSourceService" android:exported="true" android:label="@string/my_complication_service_label" android:icon="@drawable/complication_icon" 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> <!-- Supported types should be comma-separated, for example: "SHORT_TEXT,SMALL_IMAGE" --> <meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES" android:value="SHORT_TEXT" /> <meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="300" /> <!-- Optionally, specify a configuration activity, where the user can configure your complication. --> <meta-data android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION" android:value="MY_CONFIG_ACTION" /> </service>
Elementos de metadados
No arquivo de manifesto, observe os seguintes elementos de metadados:
-
android:name="android.support.wearable.complications.SUPPORTED_TYPES": especifica os tipos de dados de complicação que a fonte de dados aceita. -
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS": especifica a frequência com que o sistema precisa verificar se há atualizações nos dados.
Quando a fonte de dados de complicação está ativa,
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.
Adicionar uma atividade de configuração
Se necessário, uma fonte de dados pode incluir uma atividade de configuração, que é mostrada ao usuário quando ele escolhe essa fonte de dados específica no seletor de complicações. Por exemplo, uma fonte de dados de relógio mundial pode ter uma atividade de configuração que permite ao usuário escolher a cidade ou o fuso horário a ser exibido.
O manifesto de exemplo inclui um elemento meta-data com a
chave PROVIDER_CONFIG_ACTION. O valor desse elemento é a ação usada
para iniciar a atividade de configuração.
Crie a atividade de configuração e adicione um filtro de intent que corresponda à ação dela no arquivo de manifesto.
<intent-filter> <action android:name="MY_CONFIG_ACTION" /> <category android:name="android.support.wearable.complications.category.PROVIDER_CONFIG" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
A atividade pode receber detalhes do slot de complementos que está configurando na intent
no método onCreate() da atividade:
// Keys defined on ComplicationDataSourceService val id = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_ID, -1) val type = intent.getIntExtra(EXTRA_CONFIG_COMPLICATION_TYPE, -1) val source = intent.getStringExtra(EXTRA_CONFIG_DATA_SOURCE_COMPONENT)
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 a fonte de dados
será definida:
setResult(RESULT_OK) // Or RESULT_CANCELED to cancel configuration finish()
Usar atualizações push
Em vez de especificar um intervalo de atualização no manifesto do app, é possível usar uma instância de
ComplicationDataSourceUpdateRequester para iniciar atualizações de forma dinâmica.
Para solicitar uma atualizaçã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 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. As classes abaixo permitem criar esses valores que dependem do horário:
-
TimeFormatComplicationText: formata um valor de data ou hora. -
TimeDifferenceComplicationText: faz uma contagem progressiva ou regressiva até um horário especificado.
Dados da Linha do Tempo
Para fontes de dados de complicação que fornecem uma sequência de valores em horários predefinidos, use
SuspendingTimelineComplicationDataSourceService.
Um exemplo disso seria uma fonte de dados de "próximo evento" de um app de agenda: em vez de o sistema precisar consultar a fonte de dados regularmente para o próximo evento, a fonte de dados pode fornecer uma linha do tempo de eventos uma vez e, em seguida, iniciar atualizações se a agenda mudar. Isso minimiza a carga no sistema e permite que a complicação mostre o evento correto em tempo hábil:
class MyTimelineComplicationDataSourceService : SuspendingTimelineComplicationDataSourceService() { override suspend fun onComplicationRequest(request: ComplicationRequest): ComplicationDataTimeline? { if (request.complicationType != ComplicationType.SHORT_TEXT) { return ComplicationDataTimeline( defaultComplicationData = NoDataComplicationData(), timelineEntries = emptyList() ) } // Retrieve list of events from your own datasource / database. val events = getCalendarEvents() return ComplicationDataTimeline( defaultComplicationData = shortTextComplicationData("No event"), timelineEntries = events.map { TimelineEntry( validity = TimeInterval(it.start, it.end), complicationData = shortTextComplicationData(it.name) ) } ) } override fun getPreviewData(type: ComplicationType): ComplicationData? { return shortTextComplicationData("Event 1") } private fun shortTextComplicationData(text: String) = ShortTextComplicationData.Builder( text = PlainComplicationText.Builder(text).build(), contentDescription = PlainComplicationText.Builder(text).build() ) // Add further optional details here such as icon, tap action, title etc .build() // ... }
O comportamento do SuspendingTimelineComplicationDataSourceService é o seguinte:
- Quando o horário atual estiver entre o horário de início e de término de uma entrada na linha do tempo, o mostrador do relógio vai usar esse valor.
- Quando o horário atual não se enquadra em nenhuma entrada na linha do tempo, o valor padrão é usado. Por exemplo, no app de agenda, pode ser "Nenhum evento".
- Se o horário atual estiver dentro de vários eventos, o mais curto será usado.
Fornecer valores dinâmicos
A partir do Wear OS 4, algumas complicações podem mostrar valores que são atualizados com mais frequência
de acordo com os valores disponibilizados diretamente para a plataforma. Para oferecer esse recurso nas
suas complicações, use
campos
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
o campo de valor dinâmico de GoalProgressComplicationData e
DynamicComplicationText, que pode ser usado em qualquer campo
ComplicationText. Esses valores dinâmicos são baseados na biblioteca
androidx.wear.protolayout.expression.
Em determinadas situações, a plataforma não consegue 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
do
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 executa uma
versão mais antiga do Wear OS 4. Nessa situação, a plataforma usa um campo de fallback complementar,
como
getFallbackValue().
Recursos relacionados
- Repositório de exemplos do Wear OS (em inglês)