¿Cómo puedo forzar globalmente la orientación de la pantalla en Android?

Hay una serie de aplicaciones que son capaces de forzar la rotación de la pantalla. Funcionan incluso si una aplicación explícitamente quiere ser vista en otra orientación. En este momento estoy desactivando la configuración del sistema de rotación del acelerómetro y el establecimiento de mi orientación preferida. Una aplicación todavía puede anular esto.

Esta es una de las aplicaciones que puede anular la orientación solicitada de una aplicación:

https://play.google.com/store/apps/details?id=nl.fameit.rotate&hl=en

Intenté la respuesta de kagronick, pero no pude hacer que funcione. Después de jugar alrededor de un poco que finalmente lo consiguió trabajando con una ventana de superposición del sistema y la eliminación de los LayoutParams que encontré eran innecesarios. Aquí está mi solución final:

orientationChanger = new LinearLayout(this); // Using TYPE_SYSTEM_OVERLAY is crucial to make your window appear on top // You'll need the permission android.permission.SYSTEM_ALERT_WINDOW WindowManager.LayoutParams orientationLayout = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0, PixelFormat.RGBA_8888); // Use whatever constant you need for your desired rotation orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR; WindowManager wm = (WindowManager) this.getSystemService(Service.WINDOW_SERVICE); wm.addView(orientationChanger, orientationLayout); orientationChanger.setVisibility(View.VISIBLE); 

Puedes ver mi éxito en la aplicación que publiqué basándome en esto: Force Dock Rotation .

Esto puede hacerse creando un diálogo de sistema oculto. Su tipo de hack, pero es lo suficientemente loco para trabajar.

  wm = (WindowManager) content.getSystemService(Service.WINDOW_SERVICE); orientationChanger = new LinearLayout(content); orientationChanger.setClickable(false); orientationChanger.setFocusable(false); orientationChanger.setFocusableInTouchMode(false); orientationChanger.setLongClickable(false); orientationLayout = new WindowManager.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, windowType, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.RGBA_8888); wm.addView(orientationChanger, orientationLayout); orientationChanger.setVisibility(View.GONE); orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; wm.updateViewLayout(orientationChanger, orientationLayout); orientationChanger.setVisibility(View.VISIBLE); 

Como aparte, también puede cambiar globalmente la orientación de la pantalla sin forzarla en aplicaciones no compatibles. (Sé que esta pregunta se trata de sobrepasar las preferencias de las aplicaciones, pero esto sigue siendo útil y sobre todo información relevante).

  1. Conceder acceso a la configuración del sistema ( WRITE_SETTINGS ) en AndroidManifest.xml

     <uses-permission android:name="android.permission.WRITE_SETTINGS" /> 
  2. Settings importación

     import android.provider.Settings; 
  3. Asegúrese de que la rotación automática de la pantalla de Android está desactivada

     Settings.System.putInt( getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0 ); 
  4. Establezca USER_ROTATION en la configuración deseada, que debería ser una de las constantes ROTATION_ . Estos valores representan rotaciones de pantalla desde la orientación natural del dispositivo, que puede ser horizontal o vertical.

     Settings.System.putInt( getContentResolver(), Settings.System.USER_ROTATION, Surface.ROTATION_0 //Or a different ROTATION_ constant ); 

Tenga en cuenta que los cambios en USER_ROTATION persisten incluso si su aplicación no se está ejecutando o si se ha desinstalado. Si recuerdo correctamente, los usuarios pueden restablecer este valor deshabilitando y habilitando manualmente la rotación automática.

Crear una vista del sistema

Cree una View invisible que siempre se muestre encima de otras aplicaciones. View s puede especificar sus propias preferencias de orientación, por lo que la orientación de su vista puede usarse para anular las orientaciones de las vistas y aplicaciones subyacentes.

Opciones

Soy consciente de un par de diferentes tipos de vista que puede utilizar para lograr esto, cada uno con sus propias desventajas.

  1. Ventana de superposición del sistema ( TYPE_SYSTEM_OVERLAY )

    Requiere el permiso SYSTEM_ALERT_WINDOW . (Agregue lo siguiente a AndroidManifest.xml .)

     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 
  2. Ventana tostada ( TYPE_TOAST )

    No se requiere permiso, excepto en MIUI V8 .

    No se muestra en algunos tipos de ventanas, por lo que sus orientaciones pueden no verse afectadas:

    • TYPE_PRIORITY_PHONE llamadas entrantes ( TYPE_PRIORITY_PHONE )
    • Sueños ( TYPE_DREAM )
    • Protector de teclas / pantalla de bloqueo ( TYPE_KEYGUARD_DIALOG , TYPE_KEYGUARD_SCRIM )

Instrucciones

  1. Crear una View .
  2. Cree un WindowManager.LayoutParams .
    1. Establezca el type al valor que eligió anteriormente.
    2. Cero su width y height para evitar problemas con aplicaciones que no funcionarán cuando se superponen. (Por ejemplo, Android no le permitirá presionar el botón "Aceptar" cuando intente habilitar un servicio de accesibilidad si hay una ventana encima).
    3. Establezca su screenOrientation a cualquier valor de orientación que desee.

Ejemplo

Implementación

 public class ScreenOrientationEnforcer { private final View view; private final WindowManager windows; public ScreenOrientationEnforcer(Context context) { windows = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); view = new View(context); } public void start() { WindowManager.LayoutParams layout = generateLayout(); windows.addView(view, layout); view.setVisibility(View.VISIBLE); } public void stop() { windows.removeView(view); } private WindowManager.LayoutParams generateLayout() { WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); //So we don't need a permission or activity //Note that this won't work on some devices running MIUI layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST; //Just in case the window type somehow doesn't enforce this layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; //Prevents breaking apps that detect overlying windows enabling //(eg UBank app, or enabling an accessibility service) layoutParams.width = 0; layoutParams.height = 0; //Try to make it completely invisible layoutParams.format = PixelFormat.TRANSPARENT; layoutParams.alpha = 0f; //The orientation to force layoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; return layoutParams; } } 

Uso

 ScreenOrientationEnforcer screenOrientationEnforcer = new ScreenOrientationEnforcer(context); //Force screen orientation screenOrientationEnforcer.start(); //Stop forcing screen orientation screenOrientationEnforcer.stop(); 

Desventajas

  • Desde mi experiencia, la vista puede persistir si su aplicación se bloquea o se cancela. Reiniciar el dispositivo parece funcionar alrededor de esto.

Referencias

  • Asignación entre tipos de ventanas y orden z: PhoneWindowManager.windowTypeToLayerLw
  • Permisos necesarios para cada tipo de ventana: PhoneWindowManager.checkAddPermission

Puede configurar la orientación en AndroidManifest.xml. Me gusta esto:

 <activity android:name=".YourActivity" android:label="@string/your_app_name" android:screenOrientation="portrait"> 

No creo que puedas configurarlo para toda la aplicación, pero tendrás que configurarlo específicamente para cada actividad que estás mostrando.

Muchas preguntas como esta en SO, te sugiero que busques.

  • ¿Cómo puedo reducir el espaciado entre texto en mi diseño de Android?
  • BackgroundTint de Lollipop no tiene efecto en un botón
  • Corregir la forma de eliminar la casilla de la casilla de verificación completamente en API 16 e inferior
  • Cómo poner un botón entre dos diseños
  • Cómo limitar la longitud de EditText a 7 enteros y 2 decimales?
  • ¿Cómo utilizar la fuente personalizada en android xml?
  • Quitar regla de RelativeLayout antes de api 17
  • Java.lang.NullPointerException: Intenta invocar el método virtual 'int android.view.View.getImportantForAccessibility ()' en una referencia de objeto nulo
  • Agregar vistas de forma programática en un diseño (lineal) (que está dentro de un ScrollView)
  • Teclado Android Entrar / Siguiente Button handler
  • Android: vista personalizada desde un diseño inflado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.