Práticas recomendadas

Apps para dispositivos dobráveis e com várias telas

Em geral, os apps não devem depender de identificadores estáticos ou de uma lógica que dependa de alguns IDs de exibição. Na maioria dos casos, os apps precisam ser redimensionados e funcionar em diferentes telas, e o sistema precisa controlar onde localizá-los. Por exemplo, para criar uma experiência nova e exclusiva para dispositivos dobráveis e iniciar um app especial na tela externa quando o dispositivo está dobrado.

Nesse caso, a SystemUI (ou outro componente do sistema) precisa detectar a dobra, determinar se é apropriado realizar uma ação e iniciar a atividade de destino, especificando um ID de tela externa como o destino de início. Os apps não podem detectar essa ação nem realizar nenhuma ação em resposta e, em seguida, iniciar em uma tela específica. Em outras palavras, não suponha que o que funciona em um dispositivo vai funcionar em outros. Em resumo, o código específico do dispositivo aumenta a fragmentação.

Restringir o acesso a telas

Se a configuração do dispositivo exigir a restrição de acesso a uma ou mais telas, use a flag Display#FLAG_PRIVATE para designar essas telas como privadas. Isso restringe a adição de conteúdo à tela a todos, exceto ao proprietário. Qualquer tentativa de iniciar uma atividade ou adicionar uma janela por alguém que não seja o proprietário resulta em um SecurityException. Se o sistema for o proprietário da tela, ele poderá adicionar janelas e iniciar atividades.

Além disso, as entidades colocadas em uma tela sempre podem acessar essa tela. Se o proprietário iniciar uma atividade em uma tela, ela poderá iniciar outras atividades nessa tela. Por isso, o proprietário é responsável por restringir o acesso e permitir apenas apps confiáveis.

Além disso, mais restrições são adicionadas às telas virtuais porque qualquer app pode criar uma sem torná-la visível para o usuário. Se a tela virtual não for de propriedade do sistema, somente atividades com allowEmbedded serão permitidas, e o autor da chamada precisará ter a permissão ACTIVITY_EMBEDDING.

Para mais informações, consulte:

  • ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
  • ActivityDisplay#isUidPresent()
  • DisplayManagerService#isUidPresentOnDisplay()

Para controlar condicionalmente os lançamentos de atividades, use LaunchParamsController, que intercepta todos os lançamentos de atividades e permite que um componente do sistema modifique os parâmetros usados para o lançamento. Esse recurso está disponível em system_server.

Configurar as configurações de janela de exibição e as decorações do sistema

As decorações do sistema podem ser configuradas por tela em DisplayWindowSettings. Uma implementação de dispositivo pode fornecer uma configuração padrão em /data/system/display_settings.xml.

Esse valor determina se as decorações do sistema (iniciador, papel de parede, barra de navegação e outras janelas de decoração) e o IME aparecem em uma tela. Para mais detalhes, consulte DisplayWindowSettings#shouldShowSystemDecorsLocked() e DisplayWindowSettings#shouldShowImeLocked().

Para identificar a tela, use um ID exclusivo (o padrão usa DisplayInfo#uniqueId) ou um ID de porta física para telas de hardware (consulte DisplayInfo#address).

Por exemplo, a configuração de exibição a seguir ativa as decorações do sistema e o IME em uma tela simulada:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="0" />
<display
  name="overlay:1"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

No exemplo acima, uniqueId é usado para identificação de exibição no atributo "name", que, para uma exibição simulada, é overlay:1. Para uma tela integrada, um valor de exemplo pode ser "local:45354385242535243453". Outra opção é usar informações da porta de hardware e definir identifier="1" para corresponder a DisplayWindowSettings#IDENTIFIER_PORT e, em seguida, atualizar o nome para usar o formato "port:<port_id>":

<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="1" />
<display
  name="port:12345"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

Para mais detalhes, consulte Identificadores de exibição estática.

Para mais informações, consulte: