¿Cómo desactivo el cambio de orientación en Android?

287

Tengo una aplicación que me gustaría usar en modo vertical, por lo que he definido android: screenOrientation = "portrait" en el XML manifiesto. Esto funciona bien para el HTC Magic teléfono (y también evita cambios de orientación en otros teléfonos).

Pero tengo un problema con el teléfono HTC G1 cuando abro el teclado QWERTY de hardware (no el teclado virtual). Mi actividad se mantiene en modo vertical, pero parece que se reinicia y pierde todos sus estados. Esto no sucede con el HTC Hero versión de .

Mi aplicación es bastante grande, así que no quiero que se reinicie y pierda todos sus estados cuando se abre el teclado. ¿Cómo puedo evitar eso?

Vidar Vestnes
fuente

Respuestas:

317

Actualización de abril de 2013: no hagas esto. No fue una buena idea en 2009 cuando respondí la pregunta por primera vez y realmente no es una buena idea ahora. Vea esta respuesta de hackbod por razones:

Evite recargar la actividad con asinctask en el cambio de orientación en android

Agregue android:configChanges="keyboardHidden|orientation"a su AndroidManifest.xml. Esto le indica al sistema qué cambios de configuración va a manejar usted mismo, en este caso al no hacer nada.

<activity android:name="MainActivity"
     android:screenOrientation="portrait"
     android:configChanges="keyboardHidden|orientation">

Consulte Configuración de referencia de desarrollador para más detalles.

Sin embargo, su aplicación puede ser interrumpida en cualquier momento, por ejemplo, por una llamada telefónica, por lo que realmente debe agregar código para guardar el estado de su aplicación cuando está en pausa.

Actualización: a partir de Android 3.2, también debe agregar "screenSize":

<activity
    android:name="MainActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden|orientation|screenSize">

De la guía para desarrolladores Manejo de la configuración Cámbiese usted mismo

Precaución: a partir de Android 3.2 (API nivel 13), el "tamaño de la pantalla" también cambia cuando el dispositivo cambia entre orientación vertical y horizontal. Por lo tanto, si desea evitar que se reinicie el tiempo de ejecución debido al cambio de orientación al desarrollar para el nivel API 13 o superior (según lo declarado por los atributos minSdkVersion y targetSdkVersion), debe incluir el valor "screenSize" además del valor de "orientación". Es decir, debes declarar android:configChanges="orientation|screenSize". Sin embargo, si su aplicación apunta al nivel de API 12 o inferior, entonces su actividad siempre maneja este cambio de configuración en sí mismo (este cambio de configuración no reinicia su actividad, incluso cuando se ejecuta en un dispositivo Android 3.2 o superior).

Intrincaciones
fuente
36
Solo para agregar a esto y ser realmente explícito, Android puede matar sin piedad su aplicación en cualquier momento, independientemente de los cambios de orientación, por lo que debe usar onPause () y onSaveInstanceState () para guardar el estado, pase lo que pase.
Eric Mill
La actualización 3.2 fue muy útil y fue lo que me estaba bloqueando. No tenía idea de por qué mi controlador onConfigurationChanged no estaba disparando y esto era todo. ¡Gracias!
sweetlilmre
el tercer parámetro - screenSize no se puede encontrar en 2.3.x, ¿debería cambiar a screenLayout?
deadfish
2
@Lumma No, "screenSize" solo es necesario para Android 3.2 y versiones posteriores. ¿A qué nivel de API estás apuntando? Creo que solo necesita agregarlo si está apuntando al nivel 13 o superior. Actualizaré la respuesta para aclarar.
Intrincaciones
1
En caso de que sea útil para otras personas, los he encontrado a ambos <... android: configChanges = "orientación" ...> para anular los cambios y <... android: screenOrientation = "portrait" ...> a define el valor por defecto.
Sogger
97

Debe modificar AndroidManifest.xml como se menciona en Intrications (anteriormente Ashton) y asegurarse de que la actividad maneja el evento onConfigurationChanged como desea que se maneje. Así es como debería verse:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
ubershmekel
fuente
Como se ha señalado por Dmitry Zaitsev, es mejor poner el setRequestedOrientation()en onCreate().
Timmmm
3
No onConfigurationChanged()se llama antes onCreate()si es así, configurar la orientación antes de configurar contentViews en oncreate es un mejor enfoque, configurar la configuración a la que pertenece también es más limpio, por lo que esta respuesta sigue siendo buena.
Samuel
39

Siempre he encontrado que necesitas ambos

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"
m00sey
fuente
22

Como se dijo, establezca android:configChangessu Actividad (en archivo de manifiesto) en keyboardHidden|orientationy luego:

1) anular onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) Agregue esta línea a su actividad onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Es mejor que agregar la misma línea onConfigurationChanged, porque su aplicación cambiará al modo vertical y luego volverá al paisaje (sucederá solo una vez, pero es molesto).

También puede configurar android:screenOrientation="nosensor"su actividad (en manifiesto). Pero de esta manera no podrá manejar los cambios de orientación.

Dmitry Zaytsev
fuente
¿Qué debo hacer si quiero evitar la recreación de la actividad tras la rotación y, sin embargo, deseo permitir que el usuario bloquee la orientación a través de la configuración del sistema operativo?
Desarrollador de Android
@androiddeveloper que una pregunta por separado, que ya tiene una respuesta: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev
Su enlace se trata de cambiar el contenido por mí mismo cuando cambia la configuración, pero deseo evitar la rotación de la actividad (para que se mantenga exactamente como se ve) en caso de que el usuario haya optado por bloquear la orientación a través del sistema operativo configuración (disponible en algunos dispositivos a través de la configuración rápida, en el cajón de notificaciones).
Desarrollador de Android
@androiddeveloper ah, creo que lo entendí. Luego, eche un vistazo a este enlace: developer.android.com/reference/android/… Según los documentos, la orientación predeterminada ya debería tener en cuenta las preferencias del usuario. Si ese no es el caso, entonces sospecho que es un comportamiento específico del sistema operativo. Me alegraría saber de sus resultados, ahora también me interesan :)
Dmitry Zaytsev
Sé que el valor predeterminado manejará las preferencias del usuario, pero también vuelve a crear la actividad cuando gira la pantalla, que es algo que no quiero tener.
Desarrollador de Android
20

Utilizar este..

    android:screenOrientation="portrait"
Muhammad Aamir Ali
fuente
13

En el método OnCreate de su actividad, use este código:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Ahora su orientación se establecerá en vertical y nunca cambiará.

Numenor
fuente
44
Con eso no evita reiniciar la actividad cada vez que cambia la configuración de orientación.
AxeEffect
Además, esto no funciona si ingresa la Actividad de una Actividad anterior en orientación horizontal.
w3bshark
10

En el archivo AndroidManifest.xml, para cada actividad que desee bloquear, agregue la última screenOrientationlínea:

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

O android: screenOrientation = "paisaje" .

Gil Allen
fuente
8

En su archivo androidmanifest.xml :

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

o

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Jorgesys
fuente
6

Para bloquear la pantalla por código, debe usar la rotación real de la pantalla (0, 90, 180, 270) y debe conocer la posición natural de la misma, en un teléfono inteligente la posición natural será vertical y en una tableta, Será paisaje.

Aquí está el código (métodos de bloqueo y desbloqueo), se ha probado en algunos dispositivos (teléfonos inteligentes y tabletas) y funciona muy bien.

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
Pook
fuente
¿Qué parámetro se debe pasar como actividad?
WISHY
La actividad que llama al método para bloquear / desbloquear su orientación. Es un método público de utilidad estática que se llama desde diferentes actividades.
PoOk
1
Funciona muy bien, pero, en serio, Android, ¿por qué tenemos que hacer todo eso para orientar la pantalla de bloqueo?
Cocorico
si. Éste bloquea la orientación como lo hacemos en el manifiesto. Esto evitará que se invoque onConfigurationChanged. ¿Hay algún método que bloquee la interfaz de usuario en horizontal y aún invoque onConfigurationChanged? Al igual que la aplicación de cámara en Android
Ajith Memana
Hay un indicador SCREEN_ORIENTATION_LOCKED en SDK 18+ que parece funcionar, pero aún así querría usar el código anterior para admitir todos los dispositivos
DominicM
2

En Visual Studio Xamarin:

  1. Añadir:

using Android.Content.PM; a su lista de espacio de nombres de actividad.

  1. Añadir:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

como un atributo para tu clase, así:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}
Roy Doron
fuente
Esta pregunta es sobre Android, no sobre Xamarin
Trevor Hart
1

Añadir

android:configChanges="keyboardHidden|orientation|screenSize" 

a tu manifiesto.

saurabh
fuente
dentro de su etiqueta <actividad>
Ege Kuzubasioglu
0

Tenga en cuenta que ninguno de los métodos parece funcionar ahora.

En Android Studio 1, una forma simple es agregar android:screenOrientation="nosensor" .

Esto bloquea efectivamente la orientación de la pantalla.

kephalian
fuente