Expor dados a complicações

Uma complicação de mostrador do relógio exibe dados fornecidos por um provedor de dados. Provedores de dados fornecem campos brutos que contêm texto, strings, imagens e números a mostradores de relógio.

Um serviço de provedor de dados estende ComplicationProviderService para fornecer aos usuários informações úteis diretamente para o mostrador do relógio.

Criar aplicativos de provedor de dados

O Wear OS by Google envia solicitações de atualização para os aplicativos de provedor de dados quando é preciso atualizar os dados de complicação.

Para responder a solicitações de atualização do sistema, seu aplicativo de provedor de dados deve implementar o método onComplicationUpdate() da classe ComplicationProviderService. Esse método será chamado quando o sistema quiser dados do seu provedor, por exemplo, quando uma complicação que usa seu provedor se torna ativa ou quando uma quantidade fixa de tempo se passa. Um objeto ComplicationManager é passado como um parâmetro para o método onComplicationUpdate e pode ser usado para enviar dados ao sistema.

Observação: quando você fornece dados como um provedor de dados de complicação, o mostrador do relógio recebe os valores brutos que você enviar para desenhá-los no mostrador.

O snippet de código a seguir 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, we grab an incrementing number from SharedPrefs.
    val preferences = getSharedPreferences(
            ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY,
            0
    )

    val number: Int = preferences.getInt(
            ComplicationTapBroadcastReceiver.getPreferenceKey(thisProvider, complicationId),
            0
    )
    val numberText = String.format(Locale.getDefault(), "%d!", number)

    when (dataType) {
        ComplicationData.TYPE_SHORT_TEXT ->
            ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                    .setShortText(ComplicationText.plainText(numberText))
                    .build().also { complicationData ->
                        complicationManager.updateComplicationData(complicationId, complicationData)
                    }
        else -> {
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type $dataType")
            }
            // 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, we grab 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

Aplicativos de provedor de dados deve incluir declarações específicas no manifesto do aplicativo para serem tratados como provedores de dados pelo sistema Android. Esta seção explica as configurações necessárias para os aplicativos do provedor de dados. No manifesto do aplicativo, declare o serviço e adicione um filtro de intent da ação de solicitação de atualização. O manifesto também deve proteger o serviço ao adicionar a permissão BIND_COMPLICATION_PROVIDER para garantir que somente o sistema Wear OS possa vincular serviços de provedor.

Além disso, dentro do elemento do serviço, você deve incluir um atributo android:icon. O ícone fornecido deve ser um ícone branco sólido. Drawables de vetor são recomendados para os ícones. Um ícone deve representar o provedor e será mostrado no seletor de provedores.

Veja 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>

especifique os elementos de metadados

No seu arquivo de manifesto, inclua os metadados para especificar os tipos suportados, o período de atualização e a ação de configuração, se necessário; para obter detalhes, consulte as chaves listadas para a classe ComplicationProviderService na Referência da API Wear.

Quando seu provedor de dados de complicação está ativo, o UPDATE_PERIOD_SECONDS especifica a frequência com que você deseja que o sistema verifique se há atualizações para os dados. Ele deve ser definido para o máximo de tempo possível ou para 0 quando atualizações não forem necessárias, pois atualizações muito frequentes podem afetar a duração da bateria. Observe que não é garantido que as solicitações de atualização serão enviadas com essa frequência. O sistema aplica um período de atualização mínimo de 300 segundos e, em particular, as solicitações de atualização podem ser enviadas com menos frequência quando o dispositivo estiver em modo ambiente ou o usuário não estiver com ele no pulso.

Como alternativa, você pode usar um “estilo de push" para enviar atualizações, em vez de solicitar atualizações em um cronograma fixo. Use ProviderUpdateRequester para acionar chamadas como onComplicationUpdate conforme for necessário. Por exemplo:

            <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="0"/>

Adicione uma atividade de configuração

Se necessário, um provedor pode incluir uma atividade de configuração que é mostrada para o usuário quando ele 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 uma chave de:

          <meta-data
              android:name="android.support.wearable.complications.PROVIDER_CONFIG_ACTION"
              android:value="PROVIDER_CONFIG_ACTION"/>

O valor pode ser uma ação de sua escolha.

Em seguida, crie a atividade de configuração com um filtro de intent para essa ação. A atividade de configuração deve residir no mesmo pacote que o provedor. A atividade de configuração deve retornar RESULT_OK ou RESULT_CANCELED, para informar o sistema se o provedor deve ser definido.

Mostradores de relógio seguros especificados pelo provedor

Provedores podem especificar certos mostradores de relógio como “seguros” para receber seus dados. Essa função deve ser usada somente quando um mostrador de relógio tentar usar o provedor como um padrão (veja abaixo) e o provedor confiar no aplicativo do mostrador do relógio.

Para declarar mostradores de relógio como seguros, o provedor adiciona metadados com uma chave de android.support.wearable.complications.SAFE_WATCH_FACES. O valor de metadados deve ser uma lista separada por vírgulas (espaços são ignorados). Entradas da lista podem ser nomes de componentes (de WatchFaceServices, se ComponentName.flattenToString() tiver sido chamado), ou elas podem ser nomes de pacotes (de aplicativos e, nesse caso, todos os mostradores do relógio em um aplicativo especificado é considerado seguro). Por 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"/>

fornecer imagens com proteção de pixels

Em telas suscetíveis a proteção de pixels, blocos sólidos de cor devem ser evitados no modo ambiente. Se seus ícones ou imagens incluírem blocos sólidos de cor, você também deve fornecer uma versão com proteção de pixels.

Quando fornecer um ícone usando ComplicationData.Builder#setIcon, inclua uma versão com proteção de pixels usando ComplicationData.Builder#setBurnInProtectionIcon.

Quando fornecer uma imagem usando ComplicationData.Builder#setSmallImage, inclua uma versão com proteção de pixels usando ComplicationData.Builder#setBurnInProtectionSmallImage.

Fornecer valores que dependem do horário

Algumas complicações precisam exibir um valor relacionado ao horário atual. Exemplos incluem a data atual, o tempo restante até a próxima reunião ou o horário em outro fuso horário.

Não atualize uma complicação a cada segundo ou minuto para manter esses valores atualizados; uma complicação nunca deve ser atualizada com tanta frequência. Em vez disso, especifique os valores como relativos à data ou ao horário atual usando texto que dependa de horário. Você pode usar builders na classe ComplicationText para criar esses valores que dependem do horário.