Cómo detectar cambios de orientación en Android y bloquear la actividad en modo retrato o apaisado
Si has estado desarrollando en Android durante algún tiempo, es probable que estés familiarizado con los cambios de orientación. En su mayoría, los cambios de orientación se gestionan como parte del ciclo de vida estándar de la actividad. Pero, ¿qué sucede cuando necesitas detectar cambios de orientación pero dejar la actividad bloqueada en modo retrato o apaisado?
Tu primera inclinación probablemente sea manejar los cambios de orientación tú mismo a través del manifiesto. La documentación oficial incluso podría darte la impresión de que esto es posible utilizando la anotación android:configChanges="orientation"
.
Sin embargo, cuando anulas el método onConfigurationChanged
en tu actividad, te encontrarás con un problema. Si llamas al método del padre, la orientación cambiará. Si primero cancelas el cambio de orientación, dejarás de recibir notificaciones posteriores.
La única respuesta es vigilar manualmente la orientación del dispositivo utilizando el sensor manager. Te mostraré cómo hacerlo en este tutorial. Sigue las instrucciones paso a paso o descarga e importa el proyecto directamente en Eclipse.
Paso 1: Crear un nuevo proyecto de Android en Eclipse
1. Crea un nuevo proyecto de Android en Eclipse. La versión objetivo deberá ser Android 9 (Gingerbread) o superior.
Paso 2: Bloquear la orientación de la actividad
En el archivo AndroidManifest.xml, bloquea la orientación de la actividad en modo retrato. Aquí está el código:
Cómo redondear las esquinas de un widget ImageView en Android
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
</activity>
Paso 3: Agregar vistas de texto a la interfaz de usuario
En el directorio /res/layout
, agrega algunas vistas de texto al archivo activity_main.xml
. Aquí está el código:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<TextView android:id="@+id/pitch" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pitch: " />
<TextView android:id="@+id/roll" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Roll: " />
</LinearLayout>
Paso 4: Codificar la actividad principal
En el archivo MainActivity.java
, copia y pega el siguiente código:
package com.tu.paquete;
import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mRotationSensor;
private static final int SENSOR_DELAY = 500 * 1000; // 500ms
private static final int FROM_RADS_TO_DEGS = -57;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
mSensorManager = (SensorManager) getSystemService(Activity.SENSOR_SERVICE);
mRotationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
mSensorManager.registerListener(this, mRotationSensor, SENSOR_DELAY);
} catch (Exception e) {
Toast.makeText(this, "Error de compatibilidad de hardware", Toast.LENGTH_LONG).show();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// No se necesita hacer nada aquí
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor == mRotationSensor) {
if (event.values.length > 4) {
float[] truncatedRotationVector = new float[4];
System.arraycopy(event.values, 0, truncatedRotationVector, 0, 4);
update(truncatedRotationVector);
} else {
update(event.values);
}
}
}
private void update(float[] vectors) {
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(rotationMatrix, vectors);
int worldAxisX = SensorManager.AXIS_X;
int worldAxisZ = SensorManager.AXIS_Z;
float[] adjustedRotationMatrix = new float[9];
SensorManager.remapCoordinateSystem(rotationMatrix, worldAxisX, worldAxisZ, adjustedRotationMatrix);
float[] orientation = new float[3];
SensorManager.getOrientation(adjustedRotationMatrix, orientation);
float pitch = orientation[1] * FROM_RADS_TO_DEGS;
float roll = orientation[2] * FROM_RADS_TO_DEGS;
((TextView)findViewById(R.id.pitch)).setText("Pitch: " + pitch);
((TextView)findViewById(R.id.roll)).setText("Roll: " + roll);
}
}
¡Ahora estás listo para probar el código! Carga la aplicación en un dispositivo y muévelo de un lado a otro para ver los cambios de orientación reflejados en las vistas de texto (ver Figura A).
Si no has trabajado con sensores de Android antes, aquí hay tres consejos:
- Al igual que con el acceso a hardware en general, programa de manera defensiva. No todos los dispositivos tendrán sensores y, en algunos casos, la implementación del fabricante puede tener algunas peculiaridades.
- Cuando uses sensores, no los consultes más de lo necesario, especialmente en dispositivos anteriores a Android 4.0, donde el consumo de batería no está optimizado.
- En una aplicación en producción, asegúrate de conectar las funciones
onPause
yonResume
para suspender y reiniciar el sensor manager cuando la aplicación pase al segundo plano.
En Newsmatic nos especializamos en tecnología de vanguardia, contamos con los artículos mas novedosos sobre Desarrollo, allí encontraras muchos artículos similares a Cómo detectar cambios de orientación en Android y bloquear la actividad en modo retrato o apaisado , tenemos lo ultimo en tecnología 2023.
Artículos Relacionados