Como criar aplicativos para dispositivos dobráveis

Android 10 (nível de API 29) adiciona mais compatibilidade para dispositivos dobráveis e diferentes padrões de dobragem.

Desdobrar o dispositivo para fornecer uma tela maior pode gerar impactos positivos para os usuários:

  • Em geral, uma tela maior significa uma experiência mais imersiva.
  • Com várias janelas, o usuário pode executar diferentes tarefas ao mesmo tempo.

Dobrar e desdobrar o dispositivo pode alterar o tamanho, a densidade ou a proporção da tela. Este não é um problema novo no processo de desenvolvimento para Android. Isso já acontece nestes casos de dispositivos não dobráveis:

  • Telefones: alternando entre os modos retrato e paisagem.
  • Chrome OS em execução no modo de área de trabalho: redimensionando aplicativos Android.
  • Dispositivos com várias telas.

Esta página descreve as práticas recomendadas para garantir que seu aplicativo funcione bem com dispositivos dobráveis.

Leia também o Android 10 resumo das mudanças que envolvem a compatibilidade com dispositivos dobráveis.

Continuidade de aplicativos

Ao ser executado em um dispositivo dobrável, a transição de um aplicativo pode ser feita automaticamente de uma tela para outra. Para oferecer uma experiência do usuário de alta qualidade, é muito importante que a tarefa em andamento continue sendo executada sem erros após a transição. O funcionamento do aplicativo deve ser retomado no mesmo estado e local. Os dispositivos dobráveis podem ser dobrados de várias maneiras, tanto para dentro quanto para fora:

Como o sistema acionará uma alteração na configuração durante a transição, um aplicativo deve salvar corretamente o estado da IU e ser compatível com as mudanças na configuração.

Como tornar seu aplicativo redimensionável

Seu aplicativo deve funcionar no modo de várias janelas e usar o redimensionamento dinâmico. Para fazer isso, defina resizeableActivity=true. Isso fornecerá compatibilidade máxima para qualquer formato e ambiente usado no seu aplicativo (como dispositivos dobráveis, modo de área de trabalho ou janelas de forma livre). Teste o comportamento do seu aplicativo em uma tela dividida ou com o emulador de dispositivos dobráveis.

Se o aplicativo definir resizeableActivity=false, isso informará à plataforma que ele não é compatível com o recurso de várias janelas. O sistema ainda pode redimensionar seu aplicativo ou colocá-lo no modo de várias janelas, mas a compatibilidade é implementada em todos os componentes do aplicativo com a mesma configuração (incluindo atividades, serviços e muito mais). Em alguns casos, alterações importantes (como uma mudança no tamanho da tela) podem reiniciar o processo em vez de alterar a configuração.

Por exemplo, se a atividade definir resizableActivity=false e maxAspectRatio. Quando o dispositivo não é dobrado, a configuração da atividade, o tamanho e a proporção são mantidos colocando o aplicativo no modo de compatibilidade.

Se você não definir resizeableActivity, ou defini-lo como verdadeiro, o sistema assumirá que o aplicativo é totalmente compatível com o recurso de várias janelas, além de redimensionável.

Alguns OEMs podem implementar um recurso que adiciona um pequeno ícone de reinicialização na tela sempre que a área de exibição da atividade é alterada. Assim o usuário terá a oportunidade de reiniciar a atividade na nova configuração.

Novas proporções de tela

Android 10 (nível de API 29) e versões superiores é compatível com uma ampla variedade de proporções. Com os dispositivos dobráveis, os formatos podem variar de telas superlongas e finas (como 21:9 para um dispositivo dobrado) até 1:1.

Para que seu aplicativo seja compatível com o maior número possível de dispositivos, faça testes para diferentes proporções de tela:

Se o aplicativo não for compatível com algumas dessas proporções, use maxAspectRatio (como antes) e minAspectRatio para indicar as proporções mais altas e mais baixas que podem ser gerenciadas pelo seu aplicativo. Nos casos com telas que excedem esses limites, seu aplicativo poderá ser colocado no modo de compatibilidade.

Quando existem cinco ícones na visualização de navegação inferior, os dispositivos que executam Android 10 (nível de API 29) e versões superiores garantem um tamanho de toque mínimo de 2 polegadas. Consulte a documentação da definição de compatibilidade.

Várias janelas

A capacidade de executar várias janelas é um dos benefícios das telas grandes. No passado, ter dois aplicativos lado a lado era comum em alguns dispositivos. A tecnologia foi aprimorada para que três ou mais aplicativos possam ser executados na tela ao mesmo tempo e para que eles possam compartilhar conteúdo entre si:

Se um aplicativo não for totalmente compatível com o recurso de várias janelas, ele poderá definir resizeableActivity=false. Para mais informações, leia o guia de Várias janelas.

Quando esse recurso se tornar mais comum, torne seu aplicativo compatível com a ação arraste e solte.

Retomadas múltiplas

No Android 9.0 e em versões anteriores, somente o aplicativo em foco ficará no estado retomado. Quaisquer outras atividades visíveis serão pausadas. Isso talvez gere problemas caso os aplicativos fechem os recursos ou parem de reproduzir o conteúdo durante a pausa.

Em Android 10, esse comportamento mudou para que todas as atividades permaneçam no estado retomado quando o dispositivo estiver no modo de várias janelas. Esse recurso é chamado de retomadas múltiplas. Uma atividade pode ser pausada se houver uma atividade transparente na parte superior ou se a atividade não for focável (por exemplo, o modo picture-in-picture). Talvez nenhuma atividade tenha foco em um determinado momento, quando a gaveta "Notificações" é aberta, por exemplo. Nesse caso, OnStop continuará funcionando como de costume. Esse método será chamado sempre que a atividade sair da tela.

As retomadas múltiplas também estão disponíveis em alguns dispositivos com Android 9.0. Para ativar o recurso nesses dispositivos, você pode adicionar os seguintes metadados de manifesto:

<meta-data
    android:name="android.allow_multiple_resumed_activities" android:value="true" />

Para verificar se um determinado dispositivo é compatível com esses metadados de manifesto, consulte as especificações correspondentes.

Acesso exclusivo a recursos

Para ajudar a oferecer suporte ao recurso de retomadas múltiplas, use o novo callback do ciclo de vida, Activity#onTopResumedActivityChanged().

Esse método é chamado quando uma atividade ganha ou perde a posição de retomada superior. É importante saber quando uma atividade usa um recurso compartilhado de usuário único, como o microfone ou a câmera.

protected void onTopResumedActivityChanged(boolean topResumed) {
    if (topResumed) {
        // Top resumed activity
        // Can be a signal to re-acquire exclusive resources
    } else {
        // No longer the top resumed activity
    }
}

Um aplicativo pode perder recursos por vários outros motivos, como remover uma peça de hardware compartilhada.

De qualquer forma, um aplicativo deve gerenciar normalmente eventos de perda de recursos e alterações de estado que afetam os recursos disponíveis.

Para aplicativos que usam uma câmera, é recomendável usar o método CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged(), indicando que talvez seja um bom momento para tentar acessar a câmera. Esse método está disponível em Android 10 (nível de API 29) e versões superiores.

Lembre-se de que resizeableActivity=false não garante o acesso exclusivo à câmera, já que outros aplicativos que usam o dispositivo podem ser abertos em outras telas.

Câmera no modo de várias janelas.

Seu aplicativo não precisa dispensar a câmera quando ela perde o foco. Por exemplo, mantenha a visualização da câmera enquanto o usuário interage com o aplicativo de retomada superior recém-focado. O aplicativo poderá continuar executando a câmera quando não for o de retomada superior, mas precisará gerenciar o caso de desconexão corretamente. Quando o aplicativo de retomada superior quiser usar a câmera, ele poderá abri-la, desconectando seu aplicativo. Seu aplicativo poderá reabrir a câmera quando recuperar o foco.

Depois que um aplicativo receber um callback CameraDevice.StateCallback#onDisconnected(), chamadas subsequentes na câmera do dispositivo acionarão CameraAccessException.

Várias telas

No futuro, você poderá ver telefones dobráveis compatíveis com mais de uma tela ou exibição ao mesmo tempo. O gerenciamento dessa configuração é semelhante à maneira como os desenvolvedores trabalham com telas projetadas no Chrome OS atualmente.

Android 10 (nível de API 29) e versões superiores é compatível com atividades em telas secundárias. Se uma atividade estiver sendo executada em um dispositivo com várias telas, os usuários poderão movê-la de uma tela para outra. O recurso de retomadas múltiplas também se aplica a ambientes multitelas. Várias atividades podem receber informações do usuário ao mesmo tempo.

Um aplicativo pode especificar em qual tela ele deve ser executado na inicialização ou em que momento outra atividade deve ser criada. Esse comportamento depende do modo de inicialização da atividade definido no arquivo de manifesto e dos sinalizadores de intents e opções definidas pela entidade que realiza essa ação. Consulte ActivityOptions para saber mais.

Como nas transições de dobragem, ao se mover para uma tela secundária, uma atividade poderá passar por uma atualização de contexto, redimensionamento de janela e alterações de configuração e recursos. Se a atividade gerenciar a alteração na configuração, isso será notificado em onConfigurationChanged(). Caso contrário, ela será reiniciada.

Uma atividade deve verificar a tela atual em onCreate e onConfigurationChanged, se a alteração for gerenciada. Atualize os recursos e layouts quando a tela for alterada.

Se o modo de inicialização selecionado para uma atividade permitir várias instâncias, a inicialização em uma tela secundária poderá criar uma nova instância da atividade. As duas atividades serão retomadas ao mesmo tempo.

Várias instâncias de uma atividade em diferentes telas.

Leia também sobre as APIs de várias telas, introduzidas no Android 8.0.

Recortes de tela

Os dispositivos dobráveis podem ter geometria de recorte diferente quando dobrados e desdobrados. Para evitar problemas de recorte, leia as práticas recomendadas do corte da tela.

Atividade e contexto do aplicativo

Usar o contexto certo é fundamental no recurso de várias telas. Ao acessar recursos, o contexto da atividade (que é exibido) será diferente do contexto do aplicativo (que não aparece).

O contexto da atividade tem informações sobre a tela e é sempre ajustado para a área de exibição em que aparece. Para ter as métricas e os recursos atuais de exibição, use o contexto da atividade. Isso também afeta algumas APIs do sistema que usam informações do contexto (como Aviso).

A configuração da janela de atividades e a exibição pai definem os recursos e o contexto. Para ter a exibição atual, use:

val activityDisplay = activity.windowManager.defaultDisplay

Para ter as métricas atuais da janela de atividade, use:

val windowMetrics = DisplayMetrics()
activityDisplay.getMetrics(windowMetrics)

ou:

val windowMetrics = activity.resources.displayMetrics

Como usar telas secundárias

Você pode acessar as telas disponíveis no serviço do sistema DisplayManager:

val dm = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = dm.displays

Use a classe Display para ver informações sobre uma tela específica:

Para determinar se uma atividade pode ser iniciada em uma tela:

activityManager.isActivityStartAllowedOnDisplay(context, displayId, intent)

E para iniciar uma atividade em uma tela:

val options = ActivityOptions.makeBasic()
options.launchDisplayId = targetDisplay.displayId
startActivity(intent, options.toBundle())

Compatibilidade com várias telas

O Android já é compatível com teclados de software, planos de fundo e telas de início.

Teclado de software

Um teclado pode mostrar uma tela secundária se ela estiver configurada para oferecer suporte para decorações do sistema. O editor do método de entrada será exibido automaticamente se um campo de texto solicitar uma entrada nessa tela.

Teclado em uma tela secundária.

Plano de fundo

Em Android 10 (nível de API 29) e versões superiores, as telas secundárias podem ter um plano de fundo. A biblioteca cria uma instância separada de WallpaperService.Engine para cada tela. Verifique se a superfície de cada mecanismo é desenhada de maneira independente. Os desenvolvedores podem carregar recursos usando o contexto da tela em WallpaperService.Engine#getDisplayContext(). Além disso, verifique se o arquivo WallpaperInfo.xml é definido como android:supportsMultipleDisplays="true".

Planos de fundo em um telefone e uma tela secundária.

Tela de início

Existe uma nova categoria de filtro de intent SECONDARY_HOME para fornecer uma atividade dedicada para telas secundárias. As instâncias dessa atividade são usadas em todas as telas compatíveis com decorações do sistema, uma para cada tela.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

A atividade precisa ter um modo de inicialização que não impeça várias instâncias e possa se adaptar a diferentes tamanhos de tela. Não é possível usar os modos de inicialização singleInstance nem singleTask.

Como exemplo, a implementação do AOSP de Launcher3 é compatível com uma atividade SECONDARY_HOME.

Tela de início do Material Design no telefone.

Tela de início do Material Design em uma tela secundária.

Teste

Para deixar seu aplicativo pronto para dispositivos dobráveis, faça teste dos efeitos destes recursos:

  • Alterações de configuração
  • Várias janelas e retomadas múltiplas
  • Redimensionamento e novas proporções de tela

Emuladores de dispositivos dobráveis

O emulador do AOSP é compatível com dispositivos dobráveis. Assim os desenvolvedores podem testar os aplicativos em cenários de dobragem.

Emulador de dispositivos dobráveis 7.3’’

7.3” Tamanho Resolução Tela lógica
da tela X Y densityDpi Tamanho
Não dobrado 7.3 1536 2152 420 Grande
Dobrado 4,6 840 1960 420 Normal

**emulador de dispositivos dobráveis 8’’ **

8” Tamanho Resolução Tela lógica
da tela X Y densityDpi Tamanho
Não dobrado 8,03 2200 2480 420 Grande
Dobrado 6,62 1148 2480 420 Normal

Emulador de dobragem do AOSP.

Testes com várias telas

A nova opção para desenvolvedores chamada Forçar modo de área de trabalho permite ativar a compatibilidade com a decoração do sistema em todas as telas secundárias e exibir o ponteiro do mouse no local em vez de na tela padrão. Quando usado com Ativar janelas de forma livre, o recurso Forçar modo de área de trabalho simula uma experiência de área de trabalho com várias janelas e a capacidade de redimensionamento.

No Pixel, você pode usar essa funcionalidade com Tela simulada. Se você tiver um dispositivo compatível com HDMI ou Displayport por meio do USB tipo C, será possível fazer o teste com uma conexão com fio.

Tela simulada.