No Android 8.0, os usuários podiam alternar entre os modos de rotação automática e rotação retrato usando um Bloco de Configurações rápidas ou as configurações de exibição. No Android 9, atualizamos o modo de rotação de retrato para eliminar rotações involuntárias fixando a rotação da tela atual, mesmo que a posição do dispositivo mude. Os usuários podem acionar a rotação manualmente quando necessário pressionando um novo botão na barra de navegação. Renomeamos o modo retrato para "Bloqueio de rotação", que é ativado quando o giro automático está desativado. Não há mudanças no modo de giro automático.
Quando o dispositivo está no modo de bloqueio de rotação, os usuários podem bloquear a tela para qualquer
rotação compatível com a atividade visível na parte de cima (considerando as restrições
atual do sistema). Se a atividade principal puder ser renderizada em várias rotações no
modo de rotação automática, as mesmas opções estarão disponíveis no modo de rotação
bloqueada, com algumas exceções com base na configuração
screenOrientation
da atividade.
O modo de bloqueio de rotação funciona mostrando um botão na barra de navegação nas mudanças de
rotação do dispositivo. Para fazer isso, o sensor de orientação do dispositivo precisa permanecer ativo,
mesmo quando a rotação automática estiver desativada. Tocar nesse botão define a preferência de rotação
do usuário (Settings.System.USER_ROTATION
). O WindowManager usa essa
preferência, junto com outros detalhes sobre a atividade principal e o status do sistema,
para mudar a rotação do sistema. O WindowManager continua usando a preferência de rotação
do usuário ao decidir em qual rotação renderizar o sistema ao passar para
outra atividade.

A preferência de rotação do usuário precisa ser mantida ao alternar entre atividades. No entanto, como a maioria dos usuários de smartphones só quer usar o modo paisagem por um período curto e temporário, adicionamos o viés de orientação natural. A preferência de rotação do usuário é redefinida para a orientação natural do dispositivo sempre que a rotação do sistema muda para a orientação natural do dispositivo. Para a maioria dos smartphones, a orientação natural do dispositivo é retrato (0º). A redefinição da preferência de rotação do usuário geralmente acontece ao usar um app somente em modo retrato, bloquear o smartphone ou voltar ao espaço de trabalho da tela de início.
As interações de rotação para os usuários não mudaram muito na última década. Os usuários podem ter dificuldade para descobrir esse recurso devido ao histórico anterior de rotação e posicionamento de botões na barra de navegação. Por esse motivo, adicionamos um modo de introdução ao botão de rotação que destaca o botão quando ele aparece. O comportamento do modo de introdução só acontece nas primeiras interações com o botão, depois que o modo de introdução é desativado.
Origem
O suporte a sugestões de rotação foi adicionado ao Android 9. A maioria das mudanças está contida nos seguintes arquivos.
services/.../server/policy/PhoneWindowManager.java
:- Hooks que consomem a saída de
WindowOrientationListener
(MyOrientationListener
, responsável por monitorar sensores para determinar se o dispositivo foi girado) - Mantém o
WindowOrientationListener
ativo mesmo quando a rotação automática está desativada (consulteneedSensorRunningLp()
). - Calcula a rotação do sistema de acordo com a preferência de rotação do usuário, as configurações
screenOrientation
da atividade principal e o status do sistema (consulterotationForOrientationLw()
). - Determine se a atividade principal pode girar para uma determinada rotação (consulte
isRotationChoicePossible()
).
- Hooks que consomem a saída de
SystemUI/.../statusbar/phone/NavigationBarFragment
:- Determina se o botão da barra de navegação precisa ser mostrado em
callbacks de sugestão de rotação de
PhoneWindowManager
(consulteonRotationProposal()
). - Processa quando ocultar o botão da barra de navegação de rotação (consulte as chamadas para
setRotateSuggestionButtonState(false)
). - Processa os tempos limite dos botões, incluindo o caso especial em que a navbar está oculta (geralmente em tela cheia)
- Redefine a preferência do usuário ao retornar à orientação
natural do dispositivo (
mRotationWatcher
). - Escolhe o estilo adequado para a animação do botão da barra de navegação,
aplicada em
NavigationBarView
(consulteonRotationProposal()
). - Adiciona a lógica do modo de apresentação, incluindo animação especializada
(consulte as referências a
Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED
) - Implementa a flag de rotação disable2 (consulte
disable()
).
- Determina se o botão da barra de navegação precisa ser mostrado em
callbacks de sugestão de rotação de
SystemUI/.../statusbar/phone/NavigationBarView.java
:- A animação do ícone do botão de estilo foi estilizada para corresponder à rotação pendente (consulte
updateRotateSuggestionButtonStyle()
). - Processa mudanças na visibilidade do botão (confira
setRotateButtonVisibility()
), incluindo a lógica para ocultar o botão de rotação se determinados serviços de acessibilidade estiverem ativos (considerando a classificação da pilha de botões da barra de navegação mais à direita)
- A animação do ícone do botão de estilo foi estilizada para corresponder à rotação pendente (consulte
SystemUI/res/layout/menu_ime.xml
:- Inclui um novo
KeyButtonView
para o botão de rotação, empilhado acima do menu e do seletor de IME/teclado, mas abaixo do botão "Acessibilidade"
- Inclui um novo
SystemUI/res/drawable/ic_sysbar_rotate_button.xml
:AnimatedVectorDrawable
complexo usado para animar o botão de navegação rotativo- O estilo (em
SystemUI/res/values/styles.xml
) é usado para definir os ângulos inicial e final da rotação para que o mesmo drawable possa ser usado para animar várias rotações iniciais e finais. - A cor do ícone é definida por
TintedKeyButtonDrawable
Implementação
O Android 9 inclui todas as mudanças necessárias para que as sugestões de rotação funcionem em dispositivos que usam teclas de navegação de software (voltar, tela inicial etc.).
Os fabricantes de dispositivos que criam dispositivos com teclas de navegação de hardware que desejam implementar esse recurso precisam projetar e implementar o próprio affordance da IU do sistema ou desativar o recurso. É recomendável que qualquer superfície introduzida seja fácil de usar quando o dispositivo é mantido a 90º ou 180º em relação à rotação atual do sistema e seja acessível rapidamente. Por esses motivos, o uso de notificações (como é feito para o seletor de IME/teclado) não é recomendado.
Os requisitos de hardware para usar esse recurso são os mesmos para usar a rotação automática.
Para a consistência da implementação, é necessário que a preferência de rotação do usuário
(Settings.System.USER_ROTATION
) seja redefinida para a rotação natural
do dispositivo quando o sistema muda para a rotação natural do dispositivo por qualquer motivo
quando a rotação automática está desativada. A implementação fornecida faz isso (consulte
NavigationBarFragment.mRotationWatcher
).
Há uma nova flag em StatusBarManager.disable2
para impedir temporariamente
que as sugestões de rotação apareçam. Consulte
StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS
. Essa flag precisa ser
respeitada em todas as implementações, já que é usada por apps críticos do sistema, incluindo
o Assistente de configuração. A implementação fornecida oferece suporte a isso (consulte
NavigationBarFragment.disable()
).
É altamente recomendável ativar o recurso e seguir a implementação do AOSP, se possível. Nosso objetivo é manter a experiência de rotação semelhante entre os dispositivos, refletindo a uniformidade da experiência na maioria dos smartphones entre a rotação automática e o bloqueio de retrato.
Personalização
Como as sugestões de rotação aparecem apenas no modo de rotação bloqueada (rotação automática desativada),
é possível escolher se o recurso está ativado por padrão para novas instalações
desativando a rotação automática por padrão. Consulte
def_accelerometer_rotation
em
SettingsProvider/res/values/defaults.xml
para fazer mudanças padrão.
Os usuários podem mudar facilmente se o giro automático está ativo ou não (independentemente do padrão) pelo bloco de rotação nas Configurações rápidas ou nas Configurações de exibição.
Validação
Para testes, o recurso pode ser ativado e desativado alterando um valor
Settings.Secure
de restrição. Isso é mais fácil de fazer executando o
comando a seguir em uma instância privilegiada do adb:
adb shell settings put secure show_rotation_suggestions <x>
Defina x como 0
para desativar e 1
para ativar.
Para testes, o modo de introdução pode ser redefinido alterando o valor
Settings.Secure
associado. Isso é mais fácil de fazer executando o
comando a seguir em uma instância privilegiada do adb:
adb shell settings put secure num_rotation_suggestions_accepted 0