Expor dados a complicações

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

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

Criar apps de provedor de dados

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

Para responder a solicitações de atualização do sistema, seu app de provedor de dados precisa 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ê envia 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

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 possa se vincular aos serviços do provedor.

Além disso, um atributo android:icon precisa ser incluído dentro do elemento de serviço. O ícone disponibilizado deve ser um ícone branco sólido. Drawables de vetor são recomendados para os ícones. Um ícone serve para 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>
    

Especificar os elementos de metadados

No seu arquivo de manifesto, inclua metadados para especificar os tipos compatíveis, o período de atualização e a ação de configuração, se necessário. Para ver 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, UPDATE_PERIOD_SECONDS especifica a frequência com que você quer que o sistema verifique se há atualizações para os dados. Ele deve ser definido como o tempo máximo possível ou como 0 quando atualizações programadas não são necessárias, já que atualizações muito frequentes podem afetar a duração da bateria. Não existe garantia de que as solicitações de atualização sejam 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 poderão 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, use um “estilo de push" para enviar atualizações, em vez de solicitar atualizações em um cronograma fixo. Use ProviderUpdateRequester para acionar chamadas para onComplicationUpdate conforme 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"/>

    

Adicionar uma atividade de configuração

Se necessário, um provedor pode incluir uma atividade de configuração que é exibida ao 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 contendo o seguinte:

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

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

Em seguida, crie a atividade de configuração com um filtro de intent para essa ação. A atividade de configuração precisa residir 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 certos mostradores do relógio como "seguros" para receber os dados deles. Essa função deverá ser usada somente quando um mostrador de relógio tentar usar o provedor como um padrão (veja abaixo) e o provedor confiar no app do mostrador do relógio.

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

Usar imagens com proteção de pixels

Em telas suscetíveis à 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, ofereça também uma versão com proteção de pixels.

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

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

Usar valores que dependem do horário

Algumas complicações precisam exibir um valor relacionado ao horário atual. Os exemplos incluem a data atual, o tempo restante até a próxima reunião ou a hora 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 precisa ser atualizada com tanta frequência. Em vez disso, especifique os valores como relativos à data ou ao horário atual usando texto dependente de horário. Você pode usar builders na classe ComplicationText para criar esses valores que dependem do horário.