Criar um app de ponto de interesse

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Esta seção detalha os diferentes recursos da biblioteca que você pode usar para implementar a funcionalidade do seu app de ponto de interesse (PDI).

Declarar suporte à categoria no manifesto

Seu app precisa declarar a categoria de app para carros androidx.car.app.category.POI no filtro de intent da classe CarAppService dele.

<application>
    ...
   <service
       ...
        android:name=".MyCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.POI"/>
      </intent-filter>
    </service>
    ...
<application>

Acessar o modelo de mapa

Os apps podem acessar o PlaceListMapTemplate projetado especificamente para exibir uma lista de pontos de interesse ao lado de um mapa renderizado pelo host.

Para ter acesso a esse modelo, seu app precisa declarar a permissão androidx.car.app.MAP_TEMPLATES no AndroidManifest.xml:

<uses-permission android:name="androidx.car.app.MAP_TEMPLATES"/>

Atualizar conteúdo do PlaceListMapTemplate

Você pode permitir que os motoristas atualizem o conteúdo com um simples toque de botão enquanto navegam em listas de lugares criadas com o PlaceListMapTemplate. Implemente o método onContentRefreshRequested da interface OnContentRefreshListener e use PlaceListMapTemplate.Builder.setOnContentRefreshListener para definir o listener no modelo e ativar a atualização da lista.

O snippet a seguir mostra a definição do listener no modelo.

Kotlin

PlaceListMapTemplate.Builder()
    ...
    .setOnContentRefreshListener {
        // Execute any desired logic
        ...
        // Then call invalidate() so onGetTemplate() is called again
        invalidate()
    }
    .build()

Java

new PlaceListMapTemplate.Builder()
        ...
        .setOnContentRefreshListener(() -> {
            // Execute any desired logic
            ...
            // Then call invalidate() so onGetTemplate() is called again
            invalidate();
        })
        .build();

O botão "Atualizar" só é exibido no cabeçalho do PlaceListMapTemplate quando o listener tem um valor.

Quando o motorista clica no botão "Atualizar", o método onContentRefreshRequested da implementação do seu OnContentRefreshListener é chamado. Em onContentRefreshRequested, chame o método Screen.invalidate. Em seguida, o host vai chamar o método Screen.onGetTemplate do app para recuperar o modelo com o conteúdo atualizado. Consulte Como atualizar o conteúdo de um modelo para ver mais informações sobre a atualização de modelos. Contanto que o próximo modelo retornado por onGetTemplate seja do mesmo tipo, ele vai ser contabilizado como uma atualização e não vai ser contabilizado na cota do modelo.

Integrar com o Google Assistente usando as Ações no app

As Ações no app permitem que os usuários abram e controlem apps Android com a própria voz usando o Google Assistente. Para integrar o Google Assistente a apps de ponto de interesse, adicione um recurso com as Ações no app. Os recursos são uma expressão da funcionalidade relevante de um app e contêm uma intent integrada (BII, na sigla em inglês) e o fulfillment dela. Por exemplo, eles possibilitam que os usuários digam "Ok Google, encontre um estacionamento na rua com o app ExampleApp" para que seu aplicativo abra a tela correta.

Limitações

As Ações no app têm as seguintes limitações:

  • Estão disponíveis apenas para apps que usam a biblioteca Car App na categoria de pontos de interesse.
  • O suporte para comandos de voz é apenas para intents integradas de estacionamento ou recarga.
  • O fulfillment das Ações no app só pode ser realizado com links diretos.

Etapas de integração

  1. Adicione o seguinte elemento <meta-data> ao elemento <application> do arquivo AndroidManifest.xml:

     <meta-data
         android:name="android.app.shortcuts"
         android:resource="@xml/shortcuts" />
    
  2. Para permitir que o Google Assistente se vincule ao conteúdo do seu app usando links diretos, você precisa de um elemento <intent-filter> no arquivo AndroidManifest.xml.

    • No Android Auto, o intent-filter é o mesmo do app para dispositivos móveis.

    • Para realizar o fulfillment do Android Automotive OS, as Ações no app são acionadas pelas sessões do CarAppService. Para permitir que uma sessão acione seu link direto, você precisa especificar um filtro de intent no elemento <activity> do arquivo AndroidManifest.xml.

    <activity
      ...
      android:name="androidx.car.app.activity.CarAppActivity">
      …
      <intent-filter>
          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data
            android:scheme="YOUR_SCHEME"
            android:host="YOUR_HOST" />
      </intent-filter>
    </activity>
    
  3. Crie um arquivo shortcuts.xml no diretório res/xml do projeto do seu app com os recursos adequados:

    <?xml version="1.0" encoding="utf-8"?>
    <shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
      <!-- Your Capability definitions will go here -->
    </shortcuts>
    

    Consulte as seções "Recursos" abaixo para ver informações sobre os recursos de estacionamento e recarga.

  4. Atualize seu app para processar o fulfillment de uma sessão.

    Veja a seguir exemplos do processamento de intents para Session.onCreateScreen e Session.onNewIntent.

    onCreateScreen

    Kotlin

    @Override
    fun onCreateScreen(@NonNull intent: Intent): Screen {
      if (intent.getData() != null) {
          val uri: Uri = intent.getData()
          // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center"
          // Build your Templates with parsed uri parameters
      ...
     }
    }
    

    Java

    @Override
    public Screen onCreateScreen(@NonNull Intent intent) {
     if (intent.getData() != null) {
       Uri uri = intent.getData();
       // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center"
       // Build your Templates with parsed uri parameters
      …
     }
    }
    

    onNewIntent

    Kotlin

    @Override
    fun onNewIntent(@NonNull intent: Intent): Screen {
      if (intent.getData() != null) {
          val uri: Uri = intent.getData()
          // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center"
          // Build your Templates with parsed uri parameters
          …
      }
    }
    

    Java

    @Override
    public void onNewIntent(@NonNull Intent intent) {
     if (intent.getData() != null) {
       Uri uri = intent.getData();
       // uri = "YOUR_SCHEME://YOUR_HOST?name=Levis%20center"
       // Build your Templates with parsed uri parameters
       …
     }
    }
    

Recursos

As Ações no app oferecem suporte aos seguintes recursos:

Estacionamento

ID da ação: actions.intent.GET_PARKING_FACILITY

Descrição: encontrar um estacionamento. Ela pode especificar um tipo de estacionamento, nome de app e localização.

Localidades com suporte: en-US.

Parâmetros:

  • parkingFacility.disambiguatingDescription: um descritor para o tipo de estacionamento, por exemplo, "grátis", "manobrista" ou "rua". Você pode filtrar o tipo de estacionamento usando esse parâmetro.
  • Os parâmetros a seguir podem ajudar a determinar a localização do estacionamento solicitado pelo usuário. Se nenhum deles estiver presente, retorne os estabelecimentos mais próximos da localização atual do usuário.
    • parkingFacility.name: um nome para o local do estacionamento, por exemplo, "Mountain View".
    • parkingFacility.address: um endereço para o local do estacionamento, por exemplo, "123 Easy St, Mountain View, CA".
    • parkingFacility.geo.latitude: a latitude da instalação, por exemplo, "37.3861".
    • parkingFacility.geo.longitude: a longitude da instalação, por exemplo, "-122.084".

Definição do capability de exemplo:

<?xml version="1.0" encoding="utf-8"?>
<!-- This is a sample shortcuts.xml -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">

  <capability android:name="actions.intent.GET_PARKING_FACILITY">
    <intent>
      <url-template
       android:value="YOUR_SCHEME://YOUR_HOST{?name,address,disambiguatingDescription,latitude,longitude}">

      <!-- Eg. name = "Googleplex" -->
      <parameter
        android:name="parkingFacility.name"
        android:key="name"/>
      <!-- Eg. address = "1600 Amphitheatre Pkwy, Mountain View, CA 94043" -->
      <parameter
        android:name="parkingFacility.address"
        android:key="address"/>
      <!-- Eg. disambiguatingDescription = "valet" -->
      <parameter
        android:name="parkingFacility.disambiguatingDescription"
        android:key="disambiguatingDescription"/>
      <!-- Eg. latitude = "37.3861" -->
      <parameter
        android:name="parkingFacility.geo.latitude"
        android:key="latitude"/>
      <!-- Eg. longitude = "-122.084" -->
      <parameter
        android:name="parkingFacility.geo.longitude"
        android:key="longitude"/>
    </intent>
  </capability>
</shortcuts>

Recarga

ID da ação: actions.intent.GET_CHARGING_STATION

Descrição: encontrar uma estação de recarga. É possível especificar o nome do app ou um local.

Localidades com suporte: en-US.

Parâmetros:

  • chargingStation.disambiguatingDescription: um descritor para o tipo de estação, por exemplo, "grátis" ou "paga". É possível filtrar o tipo de estação de recarga usando esse parâmetro.
  • Os parâmetros a seguir podem ajudar a determinar a localização da estação de recarga solicitada pelo usuário. Se nenhum deles estiver presente, retorne as estações mais próximas da localização atual do usuário.
    • chargingStation.name: um nome para o local da estação, por exemplo, "Mountain View".
    • chargingStation.address: um endereço para o local da estação, por exemplo, "123 Easy St, Mountain View, CA".
    • chargingStation.geo.latitude: a latitude da estação, por exemplo, "37.3861".
    • chargingStation.geo.longitude: a longitude da estação, por exemplo, "-122,084".

Definição do capability de exemplo:

<?xml version="1.0" encoding="utf-8"?>
<!-- This is a sample shortcuts.xml -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <capability android:name="actions.intent.GET_CHARGING_STATION">
    <intent>
      <url-template
       android:value="YOUR_SCHEME://YOUR_HOST{?name,address,latitude,longitude,type}">

      <!-- Eg. name = "Googleplex" -->
      <parameter
        android:name="chargingStation.name"
        android:key="name"/>
      <!-- Eg. address = "1600 Amphitheatre Pkwy, Mountain View, CA 94043" -->
      <parameter
        android:name="chargingStation.address"
        android:key="address"/>
      <!-- Eg. latitude = "37.3861" -->
      <parameter
        android:name="chargingStation.geo.latitude"
        android:key="latitude"/>
      <!-- Eg. longitude = "-122.084" -->
      <parameter
        android:name="chargingStation.geo.longitude"
        android:key="longitude"/>
    </intent>
  </capability>
</shortcuts>