As fontes de dados de complementos expõem informações para complicações do mostrador do relógio, fornecendo texto, imagens e números que podem ser renderizados.
Um serviço de fonte de dados estende
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 à sua fonte de dados.
Para responder às solicitações de atualização, sua fonte de dados precisa implementar o método
onComplicationRequest()
da classe
SuspendingComplicationDataSourceService
.
O sistema Wear OS chama onComplicationRequest()
quando precisa de dados da sua
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 a seguir 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 e.g. 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, the complication can be configured by the user by specifying a configuration activity. --> <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 compatíveis com a fonte de dados. -
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
: Especifica a frequência com que o sistema deve verificar 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 quando o usuário 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 complicação que está configurando no intent
dentro do 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ções no manifesto do app, você pode 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 seguintes classes permitem criar esses valores que dependem do horário:
-
TimeFormatComplicationText
: formata um valor de data ou hora. -
TimeDifferenceComplicationText
: conta para cima ou para baixo até um horário especificado.
Dados da Linha do Tempo
Para fontes de dados de complementos 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, ela pode fornecer uma linha do tempo de eventos uma vez, e depois iniciar atualizações se a agenda mudar. Isso minimiza a carga no sistema e permite que a complicação mostre o evento correto de maneira oportuna:
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 está dentro do período de início e término de uma entrada na linha do tempo, o mostrador do relógio usa 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 Agenda, isso 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 essa capacidade nas
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 complementos 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 algumas 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 vez disso, 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á executando uma versão mais antiga do Wear OS 4. Nessa situação, a plataforma usa um campo de substituição complementar,
como
getFallbackValue()
.
Recursos relacionados
- Repositório de exemplos do Wear OS (em inglês)