Prevenir la rotación de la pantalla en Android

315

Tengo una de mis actividades que me gustaría evitar que gire porque estoy iniciando una AsyncTask, y la rotación de la pantalla hace que se reinicie.

¿Hay alguna forma de decirle a esta actividad "NO ROTAR la pantalla incluso si el usuario está sacudiendo su teléfono como un loco"?

Sephy
fuente
11
Puede lidiar con el cambio de orientación de la pantalla y AsyncTasks. Prevenir los cambios de orientación de la pantalla es solo una solución perezosa. Y no es difícil mantener viva una AsyncTask a través de los cambios de orientación :)
Romain Guy
56
Sería mucho más útil proporcionar una solución o algún código, Romain, en lugar de afirmar que "existe una solución y no es difícil".
Peter vdL
2
puedes usar setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy

Respuestas:

467

Añadir

android:screenOrientation="portrait" 

o

 android:screenOrientation="landscape" 

al <activity>elemento / s en el manifiesto y ya está.

lbedogni
fuente
95
Tenga en cuenta que esto solo oculta un error en su aplicación, lo que hace que sea menos probable que los usuarios tropiecen con él. Pero aún lo harán. Cualquier cambio de configuración puede hacer que su actividad se reinicie. Realmente necesita escribir su actividad correctamente para lidiar con la tarea asincrónica a medida que se reinicia.
hackbod
1
Esto no funcionó para mí en un caso. Tenía la pantalla configurada en horizontal antes de abrir la aplicación. Cuando abrí la aplicación, la pantalla giró a vertical y provocó una segunda llamada a asynctask.
user522559
2
Debe configurar las cosas para "abrir en modo vertical" Y "permanecer siempre en modo vertical". Hacer solo 1 no tiene sentido.
Carol
1
@hackbod independientemente, este es el número 1 en Google para "la aplicación de Android previene la rotación de la pantalla", mi necesidad no tiene nada que ver con las tareas asíncronas
chiliNUT
77
@hackbod ¿Cómo escribimos nuestra actividad correctamente para tratar este problema?
user41805
127

Puede seguir la lógica siguiente para evitar que la pantalla de rotación automática , mientras que su AsyncTaskse está ejecutando:

  1. Almacene su orientación de pantalla actual dentro de su actividad usando getRequestedOrientation().
  2. Deshabilite la orientación automática de pantalla usando setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Corre / ejecuta tu AsyncTask.
  4. Al final de su AsyncTaskrestauración, use su estado de orientación anterior setRequestedOrientation(oldOrientation).

Tenga en cuenta que hay varias formas de acceder Activity(que se ejecuta en el hilo de la interfaz de usuario) a las propiedades dentro de un AsyncTask. Puede implementar su AsyncTaskcomo una clase interna o puede usar un mensaje Handlerque empuje su Activiyclase.

Emre Yazici
fuente
99
Mucho mejor que la respuesta seleccionada.
Matej
3
gran idea :) no tienes almacenada la orientación actual de tu pantalla, puedes usar ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
fligante el
Esto parece increíble, @emre, ¡gracias! Parece "demasiado bueno para ser verdad!" Observe la gran cantidad de discusión sobre el tema: stackoverflow.com/q/3821423/294884 ... expertos en Android, ¿hay alguna desventaja aquí? Gracias de nuevo ... muchas gracias.
Fattie
3
¡¡Mierda!! Esto NO FUNCIONA si el dispositivo COMIENZA EN MODO DE PAISAJE. ¡Que demonios! Sux: O
Fattie
@Emre, este código no funciona en ciertos casos. Por ejemplo, si el usuario cambió su orientación entre el inicio de su AsyncTask y el final de la misma. Habría guardado y restaurado la orientación incorrecta entonces.
Pacerier
27

En su archivo de manifiesto, para cada actividad que desee bloquear la rotación de la pantalla, agregue: si desea bloquearlo en modo horizontal:

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

o si quieres bloquearlo en modo vertical:

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

La forma más fácil de hacer esto fue poner

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

dentro de onCreate, justo después

setContentView(R.layout.activity_main);

entonces...

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

En lugar de entrar en el AndroidManifest, podrías hacer esto:

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);
}

El único inconveniente aquí es que requiere un nivel API 18 o superior. Así que, básicamente, esta es la punta de la lanza.

Antuan Develle Claude
fuente
Esta parte está deshabilitando el botón de inicio y aplicaciones recientes e incluso después de liberar el bloqueo con SCREEN_ORIENTATION_FULL_SENSOR, está en estado deshabilitado. En 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
fuente
2

El siguiente atributo en ACTIVITY en AndroidManifest.xml es todo lo que necesita:

android:configChanges="orientation"

Entonces, el nodo de actividad completa sería:

<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
fuente
1

Añadir:

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

Agregue lo siguiente a su AndroidManifest.xml

[aplicación> src> principal> AndroidManifest.xml]

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

Ejemplo:

<?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
fuente
0

Debe agregar el siguiente código en el archivo manifest.xml. La actividad para la cual no debe rotar, en esa actividad agregue este elemento

android:screenOrientation="portrait"

Entonces no rotará.

Simon Chius
fuente
0

Puedes intentarlo de esta manera

<?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
fuente
0

Use AsyncTaskLoader para mantener sus datos seguros incluso si la actividad cambia, en lugar de usar AsyncTask, que es una mejor manera de crear aplicaciones que evitar la rotación de la pantalla.

Bbake Waikhom
fuente
0

Evite la rotación de la pantalla solo agregue esta línea siguiente en sus Manifiestos.

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

Esto funciona para mi.

DEVSHK
fuente
0

El usuario "portrait"en su archivo AndroidManifest.xml puede parecer una buena solución. Pero obliga a ciertos dispositivos (que funcionan mejor en el paisaje) a ir en vertical, sin obtener la orientación adecuada. En la última versión de Android, aparecerá un error. Entonces, mi sugerencia es mejor usar "nosensor".

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