O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Adicionar compatibilidade com o Android Automotive OS ao seu app de mídia

O Android Automotive OS permite que os usuários instalem apps no carro. Para alcançar os usuários nessa plataforma, você precisa distribuir um app otimizado para o motorista que seja compatível com o Android Automotive OS. É possível reutilizar quase todo o código e os recursos do app Android Auto, mas é necessário criar uma versão separada que atenda aos requisitos desta página.

Visão geral do desenvolvimento

Adicionar compatibilidade com o Android Automotive OS é simples e requer apenas algumas etapas:

  1. Ativar recursos automotivos no Android Studio.
  2. Criar um módulo automotivo.
  3. Atualizar suas dependências do Gradle.
  4. Adicionar configurações ou atividades de login (opcional).

Considerações sobre o design

O Android Automotive OS cuida do layout do conteúdo de mídia que recebe do serviço de navegação de mídia do app. Isso significa que seu app não desenha a IU nem inicia nenhuma atividade quando um usuário aciona a reprodução de mídia.

Se você estiver implementando atividades de configurações ou login, essas atividades precisarão ser otimizadas para veículos. Consulte as diretrizes de design (link em inglês) do Android Automotive OS ao projetar essas áreas do seu app.

Configurar seu projeto

É necessário configurar várias partes diferentes do projeto do seu app para ativar a compatibilidade com o Android Automotive OS.

Ativar recursos automotivos no Android Studio

Recomendamos o uso do Android Studio 3.6 Beta 1 ou mais recente para criar e testar seu app no Android Automotive OS. Todos os recursos do Automotive OS já estão ativados por padrão no Android Studio 3.6.

Se você preferir usar o Android Studio 3.5, siga estas etapas para ativar os recursos do Automotive OS:

  1. Verifique se o arquivo studioFlags.xml existe em um dos seguintes locais, dependendo do seu sistema operacional:

    • Windows: %USERPROFILE%\.AndroidStudio3.5\config\options
    • macOS: ~/Library/Preferences/AndroidStudio3.5/options
    • Linux: ~/.AndroidStudio3.5/config/options
  2. Adicione a seguinte entrada ao arquivo studioFlags.xml:

    <application>
        <component name="StudioFlags">
          <option name="data">
            <map>
              <entry key="npw.templates.automotive" value="true" />
            </map>
          </option>
        </component>
        </application>
        

Criar um módulo automotivo

Alguns componentes do Android Automotive OS, como o manifesto, têm requisitos específicos da plataforma. Portanto, é necessário criar um módulo que possa manter o código desses componentes separado do restante do código do seu projeto, como o código usado no app para smartphones.

Siga as etapas abaixo para adicionar um módulo automotivo ao seu projeto:

  1. No Android Studio, selecione File > New > New Module.
  2. Selecione Automotive Module e clique em Next.
  3. Preencha o campo Application/Library name. Esse é o nome do seu app que os usuários veem no Android Automotive OS.
  4. Preencha o campo Module name.
  5. Ajuste o Package name para corresponder ao seu app.
  6. Selecione API 28:Android 9.0 (Pie) como Minimum SDK e clique em Next.

    Todos os carros compatíveis com o Android Automotive OS executam o Android 9 (API de nível 28) ou uma versão mais recente. Portanto, a seleção desse valor abrange todos os carros que usam o Android Automotive OS.

  7. Selecione Add No Activity e clique em Finish.

Depois de criar seu módulo no Android Studio, abra o AndroidManifest.xml no seu novo módulo automotivo:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.media">

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" />

        <uses-feature
            android:name="android.hardware.type.automotive"
            android:required="true" />

    </manifest>
    

Você perceberá algumas informações padrão do app no elemento <application>, mas há também um elemento <uses-feature> que declara a compatibilidade com o Android Automotive OS. Observe também que não há atividades declaradas no manifesto.

Se você implementar atividades de configurações ou login, adicione-as aqui. Essas atividades são acionadas pelo sistema usando intents explícitas e são as únicas atividades que precisam ser declaradas no manifesto para seu app Android Automotive OS.

Filtros de intent

O Android Automotive OS usa intents explícitas para acionar atividades no seu app de mídia. O arquivo de manifesto não pode conter nenhuma atividade que tenha filtros de intent CATEGORY_LAUNCHER ou ACTION_MAIN.

Atividades como a do exemplo a seguir geralmente são destinadas a um smartphone ou outro dispositivo móvel. Essas atividades precisam ser declaradas no módulo que cria o app para smartphones, não no módulo que cria o app para Android Automotive OS.

<activity android:name=".MyActivity">
        <intent-filter>
            <!-- You can't use either of these intents for Android Automotive OS -->
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <!--
            In their place, you can include other intent filters for any activities
            that your app needs for Android Automotive OS, such as settings or
            sign-in activities.
            -->
        </intent-filter>
    </activity>
    

Atualize suas dependências do Gradle.

Recomendamos manter o serviço de navegação de mídia em um módulo separado que você compartilhe entre o app para smartphones e o módulo automotivo. Se você estiver usando essa abordagem, será necessário atualizar o módulo automotivo para incluir o módulo compartilhado, conforme mostrado no seguinte snippet:

my-auto-module/build.gradle

    buildscript {
      ...
      dependencies {
        ...
        implementation project(':shared_module_name')
      }
    }
    

Implementar atividades de configurações e login

Além do serviço de navegação de mídia, você também pode fornecer atividades de configurações e login otimizadas para veículos para o app Android Automotive OS. Essas atividades permitem que você forneça funcionalidades de apps que não estão incluídas nas APIs Android Media.

Implemente essas atividades somente se seu app Automotive OS precisar permitir que os usuários façam login ou especifiquem as configurações do app. Essas atividades não são usadas pelo Android Auto.

Adicionar uma atividade de configurações

Adicione uma atividade de configurações otimizada para veículos para que os usuários possam definir as configurações do seu app no carro. Sua atividade de configurações também pode fornecer outros fluxos de trabalho, como fazer login ou sair da conta de um usuário ou alternar entre contas. Lembre-se de que essa atividade só é acionada por um app em execução no Android Automotive OS. Os apps para smartphones conectados ao Android Auto não usam esse recurso.

Fluxos de trabalho da atividade de configurações

A atividade de configurações pode fornecer ao usuário diferentes fluxos de trabalho. O diagrama a seguir mostra como um usuário interage com sua atividade de configurações usando o Android Automotive OS:

Fluxos de trabalho para uma atividade de configurações

Figura 1. Fluxos de trabalho da atividade de configurações

Declarar uma atividade de configurações

Declare sua atividade de configurações no arquivo de manifesto do seu app, conforme mostrado no seguinte snippet de código:

<application>
        ...
        <activity android:name=".AppSettingsActivity"
                  android:exported="true"
                  android:theme="@style/SettingsActivity"
                  android:label="@string/app_settings_activity_title">
            <intent-filter>
                <action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
            </intent-filter>
        </activity>
        ...
    <application>
    

Implementar sua atividade de configurações

Quando um usuário inicia seu app, o Android Automotive OS detecta a atividade de configurações que você declara e exibe uma funcionalidade, como um ícone. O usuário pode selecionar essa funcionalidade ou tocar nela usando o tela do carro para navegar para a atividade. O Android Automotive OS envia a intent ACTION_APPLICATION_PREFERENCES, que solicita que seu app inicie a atividade de configurações.

Adicionar uma atividade de login

Se o app exigir que um usuário faça login antes de usá-lo, adicione uma atividade de login otimizada para veículos que processe o login e o logout do app. Você também pode adicionar fluxos de trabalho de login e logout a uma atividade de configurações, mas precisará usar uma atividade de login dedicada se o app não puder ser usado até que o usuário faça login. Lembre-se de que essa atividade só é acionada por um app em execução no Android Automotive OS. Os apps para smartphones conectados ao Android Auto não usam esse recurso.

Fluxo de trabalho da atividade de login

O diagrama a seguir mostra como um usuário interage com sua atividade de login usando o Android Automotive OS:

Fluxos de trabalho para uma atividade de login

Figura 2. Fluxos de trabalho da atividade de login

Login obrigatório na inicialização do app

Para exigir que um usuário faça login para usar seu app, o serviço de navegação de mídia precisa fazer o seguinte:

  1. No método onLoadChildren() do serviço, enviar um resultado nulo usando o método sendResult().
  2. Definir o PlaybackState da sessão de mídia como STATE_ERROR usando o método setState(). Isso informa ao Android Automotive OS que nenhuma outra operação pode ser executada até que o erro seja resolvido.
  3. Definir o código de erro PlaybackState da sessão de mídia para ERROR_CODE_AUTHENTICATION_EXPIRED. Isso informa ao Android Automotive OS que o usuário precisa de autenticação.
  4. Definir a mensagem de erro PlaybackState da sessão de mídia usando o método setErrorMessage(). Como essa mensagem de erro é voltada para o usuário, a mensagem precisa ser traduzida para a localidade dele.
  5. Definir os PlaybackState extras da sessão de mídia usando o método setExtras(). Inclua as duas chaves a seguir:

    • android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: uma string que é exibida no botão que inicia o fluxo de trabalho de login. Como essa string é voltada para o usuário, ela precisa ser traduzida para a localidade dele.
    • android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: um PendingIntent que direciona o usuário para sua atividade de login quando o usuário toca no botão referido pelo android.media.extras.ERROR_RESOLUTION_ACTION_LABEL.

O snippet de código a seguir mostra como seu app pode exigir que o usuário faça login antes de usá-lo:

Kotlin

    val signInIntent = Intent(this, SignInActivity::class.java)
    val signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
        signInIntent, 0)
    val extras = Bundle().apply {
        putString(
            "android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
            "Sign in"
        )
        putParcelable(
            "android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
            signInActivityPendingIntent
        )
    }

    val playbackState = PlaybackStateCompat.Builder()
            .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
            .setErrorMessage(
                PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
                "Authentication required"
            )
            .setExtras(extras)
            .build()
    mediaSession.setPlaybackState(playbackState)
    

Java

    Intent signInIntent = new Intent(this, SignInActivity.class);
    PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0,
        signInIntent, 0);
    Bundle extras = new Bundle();
    extras.putString(
        "android.media.extras.ERROR_RESOLUTION_ACTION_LABEL",
        "Sign in");
    extras.putParcelable(
        "android.media.extras.ERROR_RESOLUTION_ACTION_INTENT",
        signInActivityPendingIntent);

    PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f)
        .setErrorMessage(
                PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED,
                "Authentication required"
        )
        .setExtras(extras)
        .build();
    mediaSession.setPlaybackState(playbackState);
    

Depois que o usuário tiver sido autenticado, seu app precisará definir o PlaybackState novamente para um estado diferente de STATE_ERROR e, em seguida, levará o usuário de volta ao Android Automotive OS chamando o método finish() da atividade.

Implementar sua atividade de login

O Google oferece uma variedade de ferramentas de identidade que podem ser usadas para ajudar os usuários a fazer login no seu app no carro. Algumas ferramentas, como o Firebase Authentication, oferecem kits de ferramentas de pilha completa que podem ajudar a criar experiências de autenticação personalizadas. Outras ferramentas aproveitam as credenciais existentes de um usuário ou outras tecnologias para ajudar a criar experiências de login facilitadas para os usuários.

Recomendamos as seguintes ferramentas para ajudar a criar uma experiência de login mais fácil para usuários já conectados a outro dispositivo:

  • Login do Google: se você já tiver implementado o Login do Google em outros dispositivos (como o app para smartphones), também precisará implementá-lo no seu app para Android Automotive OS para oferecer compatibilidade com os usuários desse serviço.
  • Preenchimento automático do Google: se os usuários tiverem ativado o preenchimento automático do Google em outros dispositivos Android, as credenciais deles serão salvas no Gerenciador de senhas do Google. Em seguida, quando o usuário fizer login no seu app para Android Automotive OS, o preenchimento automático do Google sugerirá as credenciais salvas relevantes. O uso do preenchimento automático do Google não requer esforço de desenvolvimento de apps. No entanto, os desenvolvedores precisam otimizar os apps para ter resultados de melhor qualidade. O preenchimento automático do Google é compatível com todos os dispositivos que executam o Android Oreo 8.0 (API de nível 26) ou mais recente (incluindo o Android Automotive OS).

Gerenciar ações de login protegidas

Alguns apps permitem que um usuário acesse algumas ações anonimamente, mas exigem que ele faça login antes de poder executar outras ações. Por exemplo, um usuário pode tocar música em um app antes de fazer login, mas precisa estar logado para poder pular uma música.

Nesse caso, quando o usuário tenta executar a ação restrita (pular uma música), seu app pode sugerir que ele se autentique emitindo um erro não fatal. Ao usar esse tipo de erro, o sistema exibe a mensagem para o usuário sem interromper a reprodução do item de mídia. Para implementar o gerenciamento de erros não fatais, realize as seguintes etapas:

  1. Defina o errorCode do PlaybackState da sessão de mídia como ERROR_CODE_AUTHENTICATION_EXPIRED. Isso informa ao Android Automotive OS que o usuário precisa de autenticação.
  2. Mantenha o state do PlaybackState da sessão de mídia como está. Não defina como STATE_ERROR. Isso é o que informa ao sistema que o erro não é fatal.
  3. Defina os PlaybackState extras da sessão de mídia usando o método setExtras(). Inclua as duas chaves a seguir:

    • android.media.extras.ERROR_RESOLUTION_ACTION_LABEL: uma string que é exibida no botão que inicia o fluxo de trabalho de login. Como essa string é voltada para o usuário, ela precisa ser traduzida para a localidade dele.
    • android.media.extras.ERROR_RESOLUTION_ACTION_INTENT: um PendingIntent que direciona o usuário para sua atividade de login quando o usuário toca no botão referido pelo android.media.extras.ERROR_RESOLUTION_ACTION_LABEL.
  4. Retenha o restante do estado PlaybackState da sessão de mídia como está. Isso permite que a reprodução do item de mídia atual continue enquanto o usuário decide se fará login ou não.