As fontes de dados de complementos expõem informações aos complementos do mostrador do relógio , fornecendo texto, imagens e números que o mostrador pode renderizar.
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 dependência abaixo 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 complemento 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
onComplicationRequest() método da SuspendingComplicationDataSourceService
classe.
O sistema Wear OS chama onComplicationRequest() quando precisa de dados da sua fonte. Por exemplo, quando um complemento que usa a fonte de dados é ativado ou quando um período fixo de tempo passa.
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 uma implementação de exemplo:
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 uma fonte 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 complementos.
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 complemento que a fonte de dados oferece suporte. -
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS": especifica com que frequência o sistema deve verificar se há atualizações nos dados.
Quando a fonte de dados de complemento está ativa,
UPDATE_PERIOD_SECONDS especifica com que frequência você quer que o
sistema verifique se há atualizações nos dados. Caso não seja necessário atualizar as informações mostradas no
complemento 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 seleciona essa fonte de dados específica no seletor de complementos. 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 meta-data elemento com a
PROVIDER_CONFIG_ACTION chave. 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
dentro do onCreate() método 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
Como alternativa à especificação de um intervalo de atualização no manifesto do app, você pode usar uma instância de
ComplicationDataSourceUpdateRequester para iniciar atualizações dinamicamente.
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 a seguir 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 complemento 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 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 horário 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 está dentro de nenhuma entrada na linha do tempo, o valor padrão é usado. Por exemplo, no app de agenda, isso pode ser "Nenhum evento".
- Se o horário atual estiver dentro de vários eventos, o evento 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
com base em valores que estão disponíveis diretamente para a plataforma. Para oferecer essa capacidade nas
suas complicações, use
ComplicationData campos que aceitam
valores dinâmicos. A plataforma avalia e
atualiza esses valores com frequência, sem exigir que o provedor de complemento esteja em execução.
Os campos de exemplo incluem
GoalProgressComplicationData's campo de valor dinâmico, e
DynamicComplicationText, que pode ser usado em qualquer
ComplicationText campo. Esses valores dinâmicos são baseados na
androidx.wear.protolayout.expression biblioteca.
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
do
campo de substituição de invalidação de valor dinâmico em vez disso, no
campo de marcador de posição de um
NoDataComplicationData's. - O valor dinâmico nunca está disponível : isso acontece em um dispositivo que está sendo executado em uma versão
mais antiga do Wear OS 4. Nessa situação, a plataforma usa um campo de substituição complementar,
como
getFallbackValue().