¿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:
- Edittext se centran en el inicio y evitan el empuje del diseño
- Android: ¿La lista de capas no funciona?
- Frontera brillante de Androide
- Cómo obtener el evento onClickListener () en la barra de acciones personalizada
- No se encuentra el método de inflado para mi vinculación (mediante Android, vinculación de datos).
https://play.google.com/store/apps/details?id=nl.fameit.rotate&hl=en
- ClassCastException cuando se utiliza LinearLayout.LayoutParams
- MultiLine EditText en Android con el cursor empezando en la parte superior
- Eliminar icono / logotipo de la barra de acción de android
- Cambiar dinámicamente el color de (Elemento de lista) TextView en Listview
- Cómo actualizar mis actividades a fragmentos y evitar ClassCastException?
- Android ListActivity - ¿cómo agregar una vista debajo de ListView?
- ¿Cómo quitar los botones / menú suaves en sandwitch del helado del androide?
- No se puede desplazar en el fragmento de diálogo
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).
-
Conceder acceso a la configuración del sistema (
WRITE_SETTINGS
) en AndroidManifest.xml<uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
Settings
importaciónimport android.provider.Settings;
-
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 );
-
Establezca
USER_ROTATION
en la configuración deseada, que debería ser una de las constantesROTATION_
. 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.
-
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" />
-
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
- Crear una
View
. - Cree un
WindowManager.LayoutParams
.- Establezca el
type
al valor que eligió anteriormente. - Cero su
width
yheight
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). - Establezca su
screenOrientation
a cualquier valor de orientación que desee.
- Establezca el
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 habilitar el acceso a la ubicación mediante programación en android?
- Android Take Captura de pantalla de Vista de superficie muestra negro