Impedir a rotação da tela no Android

315

Eu tenho uma das minhas atividades que eu gostaria de impedir de rodar porque estou iniciando um AsyncTask, e a rotação da tela faz com que seja reiniciado.

Existe uma maneira de dizer a essa atividade "NÃO GIRAR A Tela, mesmo que o usuário esteja sacudindo o telefone como um louco"?

Sephy
fonte
11
Você pode lidar com alterações de orientação da tela e AsyncTasks. Evitar alterações na orientação da tela é apenas uma solução lenta. E não é difícil manter um AsyncTask vivo através mudanças de orientação :)
Romain Guy
56
Seria muito mais útil fornecer uma solução ou algum código, Romain, em vez de apenas afirmar que "existe uma solução e não é difícil".
Peter VDL
2
você pode usar setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy 29/03

Respostas:

467

Adicionar

android:screenOrientation="portrait" 

ou

 android:screenOrientation="landscape" 

para o <activity>(s) elemento (s) no manifesto e pronto.

lbedogni
fonte
95
Observe que isso apenas oculta um bug no seu aplicativo, diminuindo a probabilidade de os usuários tropeçarem nele. Mas eles ainda vão. Qualquer alteração na configuração pode fazer com que sua atividade seja reiniciada. Você realmente precisa escrever sua atividade corretamente para lidar com a tarefa assíncrona que é reiniciada.
hackbod
1
Isso não funcionou para mim em um caso. Eu tinha a tela configurada para paisagem antes de abrir o aplicativo. Quando abri o aplicativo, a tela girou para o retrato e causou uma segunda chamada para assíncrona.
user522559
2
Você precisa definir as coisas para "abrir no modo retrato" E "sempre permanecer no modo retrato". Fazer apenas 1 é inútil.
Carol
1
@hackbod independentemente, este é o número # 1 google hit para "app android impedir a rotação da tela," a minha necessidade não tem nada a ver com tarefas assíncronas
chiliNUT
7
@hackbod Como escrevemos nossa atividade corretamente para lidar com esse problema?
user41805
127

Você pode seguir a lógica abaixo para evitar auto tela girar , enquanto o seu AsyncTaskestá em execução:

  1. Armazene sua orientação atual da tela dentro de sua atividade usando getRequestedOrientation().
  2. Desative a orientação automática da tela usando setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Execute / execute o seu AsyncTask.
  4. No final da AsyncTaskrestauração, restaure o status de orientação anterior usando setRequestedOrientation(oldOrientation).

Observe que existem várias maneiras de acessar as propriedades Activity(executadas no thread da interface do usuário) dentro de um AsyncTask. Você pode implementar seu AsyncTaskcomo uma classe interna ou pode usar uma mensagem Handlerque cutuca sua Activiyclasse.

Emre Yazici
fonte
9
Muito melhor que a resposta selecionada.
Matej
3
grande ideia :) você não precisa armazenar a orientação da tela atual pode utilizar ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
fligant
Isso parece incrível, @emre, obrigado! Parece "bom demais para ser verdade!" Observe a enorme quantidade de discussão sobre o problema: stackoverflow.com/q/3821423/294884 ... especialistas em android, há alguma desvantagem aqui ?! Mais uma vez obrigado.
Fattie 19/05
3
Porcaria!! Isso NÃO FUNCIONA se o dispositivo INICIAR NO MODO PAISAGEM. Que diabos! Sux: O
Fattie
@ Emre, este código não funciona em certos casos. Por exemplo, se o usuário alterou sua orientação entre o início do seu AsyncTask e o final dele. Você teria salvo e restaurado a orientação errada então.
Pacerier
27

No seu arquivo de manifesto, para cada atividade que você deseja bloquear a rotação da tela, adicione: se você deseja bloqueá-lo no modo horizontal:

<activity
        ...
        ...
        android:screenOrientation="landscape">

ou se você deseja travá-lo no modo vertical:

<activity
            ...
            ...
            android:screenOrientation="portrait">
Sara
fonte
24

A maneira mais fácil de encontrar isso foi colocar

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

no onCreate, logo após

setContentView(R.layout.activity_main);

tão...

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Paul Alexander
fonte
7

Em vez de entrar no AndroidManifest, você pode fazer o seguinte:

screenOrientation = getResources().getConfiguration().orientation;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
... AsyncTask

screenOrientation = getResources().getConfiguration().orientation;


@Override
protected void onPostExecute(String things) {
    context.setRequestedOrientation(PlayListFragment.screenOrientation);
    or 
    context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}

A única desvantagem aqui é que ela requer o nível 18 da API ou superior. Então, basicamente, esta é a ponta da lança.

Antuan Develle Claude
fonte
Esta parte está desativando o botão de aplicativos domésticos e recentes e, mesmo depois de liberar o bloqueio com SCREEN_ORIENTATION_FULL_SENSOR, está no estado desativado. No Android N.
kAmol
6

Activity.java

@Override     
 public void onConfigurationChanged(Configuration newConfig) {       
        try {     
            super.onConfigurationChanged(newConfig);      
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {      
                // land      
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {      
               // port       
            }    
        } catch (Exception ex) {       
     }   

AndroidManifest.xml

 <application android:icon="@drawable/icon" android:label="@string/app_name">
  <activity android:name="QRCodeActivity" android:label="@string/app_name"
  android:screenOrientation="landscape" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

 </application>
Li Che
fonte
2

O seguinte atributo na ACTIVITY no AndroidManifest.xml é tudo o que você precisa:

android:configChanges="orientation"

Portanto, o nó de atividade completo seria:

<activity android:name="Activity1"
          android:icon="@drawable/icon"
          android:label="App Name"
          android:excludeFromRecents="true"
          android:configChanges="orientation">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>
Ben
fonte
1

Adicionar:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        ...
        ...
        ...
}
Anas
fonte
1

Adicione o seguinte ao seu AndroidManifest.xml

[app> src> main> AndroidManifest.xml]

<activity android:name=".MainActivity"
          android:configChanges="orientation"
          android:screenOrientation="portrait"/>

Exemplo:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.zzzzzz.yyyyy">

   <uses-permission android:name="A-PERMISSION" />

   <application>
      <activity android:name=".MainActivity"
                android:screenOrientation="portrait"
                android:configChanges="orientation">
      </activity>
   </application>

</manifest>
andrewoodleyjr
fonte
0

Se você estiver usando o Android Developer Tools (ADT) e o Eclipse, poderá acessar o AndroidManifest.xml -> guia Aplicativo -> descer e selecionar sua atividade. Por fim, selecione sua orientação preferida. Você pode selecionar uma das muitas opções.

Husam
fonte
0

Você precisa adicionar o seguinte código no arquivo manifest.xml. A atividade para a qual não deve girar, nessa atividade, adicione este elemento

android:screenOrientation="portrait"

Então não vai rodar.

Simon Chius
fonte
0

Você pode tentar dessa maneira

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itclanbd.spaceusers">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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">
    <activity android:name=".Login_Activity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

Muhaiminur Rahman
fonte
0

Use o AsyncTaskLoader para manter seus dados seguros, mesmo que a atividade seja alterada, em vez de usar o AsyncTask, que é a melhor maneira de criar aplicativos do que impedir a rotação da tela.

Bbake Waikhom
fonte
0

Impedir a rotação da tela, basta adicionar esta linha a seguir em seus manifestos.

<activity
        android:name=".YourActivity"
        android:screenOrientation="portrait" />

Isso funciona para mim.

DEVSHK
fonte
0

O usuário "portrait"no seu arquivo AndroidManifest.xml pode parecer uma boa solução. Mas força alguns dispositivos (que funcionam melhor na paisagem) a entrar em retrato, sem obter a orientação adequada. Na versão mais recente do Android, você receberá um erro. Então, minha sugestão é melhor usar "nosensor".

<activity
        ...
        ...
        android:screenOrientation="nosensor">
Md Imran Choudhury
fonte