En este tutorial, vamos a explorar cómo usar el acelerómetro, uno de los muchos sensores de hardware de los teléfonos inteligentes modernos, en una aplicación de Android. Explicaré qué es un acelerómetro y por qué puede ser algo que quiera aprovechar en sus aplicaciones de Android.
Antes del amanecer de los teléfonos inteligentes, uno de los pocos componentes de hardware con los que las aplicaciones podían interactuar era el teclado. Pero los tiempos han cambiado y la interacción con los componentes de hardware es cada vez más común..
El uso de gestos a menudo resulta más natural que interactuar con una interfaz de usuario a través del mouse y el teclado. Esto es especialmente cierto para dispositivos táctiles, como teléfonos inteligentes y tabletas. Me parece que el uso de gestos puede dar vida a una aplicación de Android, lo que la hace más interesante y emocionante para el usuario.
Un buen número de aplicaciones están haciendo uso del acelerómetro. Por ejemplo, eche un vistazo a estas plantillas de aplicaciones en Envato Market, que incluyen un juego de carreras de velocidad y un agitador de números aleatorios.
En este tutorial, usaremos un gesto que encontrará en bastantes aplicaciones móviles, el gesto de agitar. Usaremos el gesto de agitar para generar aleatoriamente seis números de Lotería y mostrarlos en la pantalla con una bonita animación..
Comience un nuevo proyecto de Android en su IDE (entorno de desarrollo integrado) favorito para el desarrollo de Android. Para este tutorial, estaré usando IntelliJ IDEA.
Si su IDE es compatible con el desarrollo de Android, habrá creado un Principal
clase para ti El nombre de esta clase puede variar según el IDE que esté utilizando. los Principal
La clase juega un papel clave cuando se inicia su aplicación. Su IDE también debería haber creado un archivo de diseño principal que Principal
La clase utiliza para crear la interfaz de usuario de la aplicación..
Dado que vamos a utilizar un gesto de sacudir, es una buena idea bloquear la orientación del dispositivo. Esto asegurará que la interfaz de usuario de la aplicación no cambie constantemente entre vertical y horizontal. Abra el archivo de manifiesto del proyecto y establezca la orientación de la pantalla
opción a retrato
.
Con nuestro proyecto configurado, es hora de ensuciarnos las manos y escribir un código. Por el momento, la clase de actividad principal tiene una onCreate
Método en el que configuramos el diseño principal invocando. setContentView
Como se muestra abajo.
clase pública principal extiende la actividad / ** llamada cuando la actividad se crea por primera vez. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main);
Dependiendo del IDE que esté utilizando, es posible que deba agregar algunas declaraciones de importación a Main.java
, el archivo en el que tu Principal
vida de clase La mayoría de los IDE insertarán estas declaraciones de importación para usted, pero quiero asegurarme de que estemos en la misma página antes de continuar. La primera declaración de importación, Importar android.app.Actividad
, importa el Actividad
clase mientras que la segunda declaración de importación, import android.os.Bundle
, importa el Haz
clase. La tercera declaración de importación, com.example.R
, Contiene las definiciones de los recursos de la aplicación. Esta declaración de importación será diferente de la que se ve a continuación, ya que depende del nombre de su paquete..
importar android.app.Activity; importar android.os.Bundle; import com.example.R;
En el siguiente paso, aprovecharemos la SensorEventListener
interfaz, que se declara en el SDK de Android. Usar el SensorEventListener
interfaz, la Principal
la clase de actividad necesita implementarla como se muestra en el fragmento de código a continuación. Si echas un vistazo a la actualización. Principal
clase de actividad, encontrarás que uso el implementos
palabra clave para decirle al compilador que el Principal
clase implementa el SensorEventListener
interfaz.
público clase Principal extiende Actividad implementa SensorEventListener / ** Llamado cuando la actividad se crea por primera vez. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main);
Usar el SensorEventListener
interfaz, debe agregar otra declaración de importación como se muestra a continuación. La mayoría de los IDE agregarán inteligentemente la declaración de importación por lo que probablemente no tendrá que preocuparse por esto.
importar android.hardware.SensorEventListener;
Desde el momento, actualizas el Principal
implementación de la clase como se muestra arriba, verá algunos errores emergentes. Esto no es sorprendente ya que necesitamos dos métodos para implementar dos métodos requeridos de SensorEventListener
interfaz.
Si está utilizando IntelliJ IDEA, se le pedirá que agregue estos métodos necesarios cuando haga clic en el error. Si está utilizando un IDE diferente, este comportamiento puede ser diferente. Agreguemos los dos métodos requeridos a mano como se muestra en el fragmento de código a continuación. Asegúrese de agregar estos métodos en el Principal
clase y fuera de la onCreate
método.
@Override public void onSensorChanged (evento SensorEvent) @Override public void onAccuracyChanged (Sensor sensor, int exactitud)
Echemos un vistazo a la onSensorChanged
método. Usaremos este método para detectar el gesto de agitar. los onSensorChanged
El método se invoca cada vez que el sensor incorporado detecta un cambio. Este método se invoca repetidamente cuando el dispositivo está en movimiento. Usar el Sensor
y SensorEvent
clases, agregamos dos declaraciones de importación adicionales como se muestra a continuación.
importar android.hardware.Sensor; importar android.hardware.SensorEvent;
Antes de implementar onSensorChanged
, Necesitamos declarar dos variables privadas en el Principal
clase, senSensorManager
de tipo SensorManager
y senAccelerómetro
de tipo Sensor
.
privado SensorManager senSensorManager; Sensor senAccelerómetro privado;
los SensorManager
clase se declara en android.hardware.SensorManager
. Si está viendo algún error emergente, verifique que el SensorManager
la clase es importada tambien.
importar android.hardware.SensorManager;
En el onCreate
Método, inicializamos las variables que acabamos de declarar y registramos un oyente. Eche un vistazo a la implementación actualizada del onCreate
método.
@Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); senSensorManager = (SensorManager) getSystemService (Context.SENSOR_SERVICE); senAccelerometer = senSensorManager.getDefaultSensor (Sensor.TYPE_ACCELEROMETER); senSensorManager.registerListener (este, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
Para inicializar el SensorManager
instancia, invocamos getSystemService
para buscar el sistema SensorManager
instancia, que a su vez utilizamos para acceder a los sensores del sistema. los getSystemService
El método se utiliza para obtener una referencia a un servicio del sistema al pasar el nombre del servicio. Con el administrador de sensores a nuestra disposición, obtenemos una referencia al acelerómetro del sistema invocando getDefaultSensor
en el administrador de sensores y pasando el tipo de sensor que nos interesa. Luego registramos el sensor usando uno de los SensorManager
los métodos públicos, registroListener
. Este método acepta tres argumentos, el contexto de la actividad, un sensor y la velocidad a la que nos envían los eventos del sensor.
público clase Principal extiende Actividad implementa SensorEventListener private SensorManager senSensorManager; Sensor senAccelerómetro privado; /** Se llama cuando se crea por primera vez la actividad. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); senSensorManager = (SensorManager) getSystemService (Context.SENSOR_SERVICE); senAccelerometer = senSensorManager.getDefaultSensor (Sensor.TYPE_ACCELEROMETER); senSensorManager.registerListener (este, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); @Override public void onSensorChanged (SensorEvent SensorEvent) @Override public void onAccuracyChanged (Sensor Sensor, int precision)
Hay otros dos métodos que debemos anular, en pausa
y En resumen
. Estos son métodos de la Principal
clase. Es una buena práctica anular el registro del sensor cuando la aplicación hiberna y volver a registrar el sensor cuando se reanude la aplicación. Eche un vistazo a los fragmentos de código a continuación para tener una idea de cómo funciona esto en la práctica..
void protegido onPause () super.onPause (); senSensorManager.unregisterListener (this);
void protegido onResume () super.onResume (); senSensorManager.registerListener (este, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
Ahora podemos empezar a centrarnos en la carne de la aplicación. Se requerirá un poco de matemáticas para averiguar cuándo se produce un gesto de sacudida. La mayor parte de la lógica entrará en el onSensorChanged
método. Comenzamos por declarar algunas variables en nuestra Principal
clase. Eche un vistazo al fragmento de código a continuación..
privado long lastUpdate = 0; flotador privado last_x, last_y, last_z; final estático privado int SHAKE_THRESHOLD = 600;
Ahora vamos a hacer un zoom sobre la implementación de la onSensorChanged
método. Tomamos una referencia a la Sensor
instancia utilizando el SensorEvent
instancia que se nos pasa. Como puede ver en el fragmento de código a continuación, verificamos que obtengamos una referencia al tipo de sensor correcto, el acelerómetro del sistema.
public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER)
El siguiente paso es extraer la posición del dispositivo en el espacio, el X
, y
, y z
eje. Eche un vistazo a la imagen de abajo para comprender mejor a qué me refiero. los X
eje define el movimiento lateral, mientras que el y
El eje define el movimiento vertical. los z
El eje es un poco más complicado ya que define el movimiento dentro y fuera del plano definido por el X
y y
hachas.
Para obtener los valores de cada eje, le pedimos al evento del sensor sus valores como se muestra a continuación. Los eventos valores
atributo es una matriz de flotadores.
public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER) float x = sensorEvent.values [0]; float y = sensorEvent.values [1]; float z = sensorEvent.values [2];
Los sensores del sistema son increíblemente sensibles. Cuando sostiene un dispositivo en su mano, está constantemente en movimiento, sin importar cuán firme sea su mano. El resultado es que el onSensorChanged
El método se invoca varias veces por segundo. No necesitamos todos estos datos, por lo que debemos asegurarnos de que solo muestreamos un subconjunto de los datos que obtenemos del acelerómetro del dispositivo. Almacenamos la hora actual del sistema (en milisegundos) almacenamos en tiempo de curación
y verifica si hay mas de 100
milisegundos han pasado desde la última vez onSensorChanged
fue invocado.
public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER) float x = sensorEvent.values [0]; float y = sensorEvent.values [1]; float z = sensorEvent.values [2]; long curTime = System.currentTimeMillis (); if ((curTime - lastUpdate)> 100) long diffTime = (curTime - lastUpdate); lastUpdate = curTime;
La pieza final del rompecabezas es detectar si el dispositivo ha sido sacudido o no. Usamos el Mates
clase para calcular la velocidad del dispositivo como se muestra a continuación. El estáticamente declarado SHAKE_THRESHOLD
La variable se usa para ver si se ha detectado o no un gesto de sacudida. Modificando SHAKE_THRESHOLD
aumenta o disminuye la sensibilidad, así que siéntete libre de jugar con su valor.
public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER) float x = sensorEvent.values [0]; float y = sensorEvent.values [1]; float z = sensorEvent.values [2]; long curTime = System.currentTimeMillis (); if ((curTime - lastUpdate)> 100) long diffTime = (curTime - lastUpdate); lastUpdate = curTime; velocidad de flotación = Math.abs (x + y + z - last_x - last_y - last_z) / diffTime * 10000; if (velocidad> SHAKE_THRESHOLD) last_x = x; last_y = y; last_z = z;
Ahora tenemos una aplicación que puede detectar un gesto de sacudida con el acelerómetro. Terminemos este proyecto usando el gesto de agitar para elegir seis números de lotería aleatorios. Te mostraré cómo generar un número aleatorio entre 1
y 49
, pero tiene la libertad de modificar mi implementación para que funcione con la forma en que se juega la lotería en su país.
Comencemos configurando el archivo de diseño principal de la aplicación que usaremos para la interfaz de usuario. Como puede ver a continuación, utilizo seis diseños de marcos con un fondo de una imagen de una bola.
Cada diseño de marco contiene una vista de texto que mostrará un número de lotería generado aleatoriamente. Tenga en cuenta que cada diseño de marco y vista de texto tiene un carné de identidad
Para asegurarnos de que podamos consultarlos más tarde..
Con el diseño principal listo para usar, revisemos el Principal
clase. Comenzamos creando getRandomNumber
, Un método privado para generar seis números aleatorios entre 1
y 49
.
private void getRandomNumber () ArrayList numbersGenerated = new ArrayList (); para (int i = 0; i < 6; i++) Random randNumber = new Random(); int iNumber = randNumber.nextInt(48) + 1; if(!numbersGenerated.contains(iNumber)) numbersGenerated.add(iNumber); else i--;
Primero creamos un Lista de arreglo
instancia, que utilizamos para almacenar los seis números en. En cada bucle de la para
Loop, aprovechamos las de Java. Aleatorio
Clase para generar un número aleatorio. Para asegurarse de que obtenemos un número entre 1
y 49
, añadimos 1
al resultado. El siguiente paso es verificar si el número generado ya está en la lista de matriz, porque solo queremos números únicos en la lista de matriz.
Tenga en cuenta que puede ser necesario agregar dos instrucciones de importación más para mantener contento al compilador.
import java.util.ArrayList; import java.util.Random;
El último paso es mostrar el número generado aleatoriamente en la interfaz de usuario. Obtenemos una referencia a las vistas de texto que creamos anteriormente y rellenamos cada vista de texto con un número aleatorio. También agregamos una animación ordenada a los diseños de cuadros, pero siéntase libre de omitir o modificar la animación..
private void getRandomNumber () ArrayList numbersGenerated = new ArrayList (); para (int i = 0; i < 6; i++) Random randNumber = new Random(); int iNumber = randNumber.nextInt(48) + 1; if(!numbersGenerated.contains(iNumber)) numbersGenerated.add(iNumber); else i--; TextView text = (TextView)findViewById(R.id.number_1); text.setText(""+numbersGenerated.get(0)); text = (TextView)findViewById(R.id.number_2); text.setText(""+numbersGenerated.get(1)); text = (TextView)findViewById(R.id.number_3); text.setText(""+numbersGenerated.get(2)); text = (TextView)findViewById(R.id.number_4); text.setText(""+numbersGenerated.get(3)); text = (TextView)findViewById(R.id.number_5); text.setText(""+numbersGenerated.get(4)); text = (TextView)findViewById(R.id.number_6); text.setText(""+numbersGenerated.get(5)); FrameLayout ball1 = (FrameLayout) findViewById(R.id.ball_1); ball1.setVisibility(View.INVISIBLE); FrameLayout ball2 = (FrameLayout) findViewById(R.id.ball_2); ball2.setVisibility(View.INVISIBLE); FrameLayout ball3 = (FrameLayout) findViewById(R.id.ball_3); ball3.setVisibility(View.INVISIBLE); FrameLayout ball4 = (FrameLayout) findViewById(R.id.ball_4); ball4.setVisibility(View.INVISIBLE); FrameLayout ball5 = (FrameLayout) findViewById(R.id.ball_5); ball5.setVisibility(View.INVISIBLE); FrameLayout ball6 = (FrameLayout) findViewById(R.id.ball_6); ball6.setVisibility(View.INVISIBLE); Animation a = AnimationUtils.loadAnimation(this, R.anim.move_down_ball_first); ball6.setVisibility(View.VISIBLE); ball6.clearAnimation(); ball6.startAnimation(a); ball5.setVisibility(View.VISIBLE); ball5.clearAnimation(); ball5.startAnimation(a); ball4.setVisibility(View.VISIBLE); ball4.clearAnimation(); ball4.startAnimation(a); ball3.setVisibility(View.VISIBLE); ball3.clearAnimation(); ball3.startAnimation(a); ball2.setVisibility(View.VISIBLE); ball2.clearAnimation(); ball2.startAnimation(a); ball1.setVisibility(View.VISIBLE); ball1.clearAnimation(); ball1.startAnimation(a);
Tendremos que agregar algunas declaraciones de importación más para que todo esto funcione. Eche un vistazo al fragmento de código a continuación..
importar android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; importar android.widget.FrameLayout; importar android.widget.TextView;
En cuanto a las animaciones, eche un vistazo al contenido del siguiente archivo de animación. Tenga en cuenta que necesita crear un anim
Carpeta en el directorio de recursos de su proyecto y nombrela move_down_ball_first.xml
. Ajustando los valores de la escala
Elemento, puedes modificar la duración de la animación y la posición de cada bola..
Todo lo que nos queda por hacer es llamar getRandomNumber
en onSensorChanged
en el Principal
clase. Eche un vistazo a la implementación completa de onSensorChanged
mostrado a continuación.
public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER) float x = sensorEvent.values [0]; float y = sensorEvent.values [1]; float z = sensorEvent.values [2]; long curTime = System.currentTimeMillis (); if ((curTime - lastUpdate)> 100) long diffTime = (curTime - lastUpdate); lastUpdate = curTime; velocidad de flotación = Math.abs (x + y + z - last_x - last_y - last_z) / diffTime * 10000; if (velocidad> SHAKE_THRESHOLD) getRandomNumber (); last_x = x; last_y = y; last_z = z;
En este tutorial, te he mostrado cómo funciona el acelerómetro y cómo puedes usarlo para detectar un gesto de sacudida. Por supuesto, hay muchos otros casos de uso para el acelerómetro. Con una comprensión básica de la detección de gestos con el acelerómetro, te animo a experimentar con el acelerómetro para ver qué más puedes hacer con él..
Si trabajas mucho con el desarrollo de Android, es probable que encuentres situaciones en las que necesites ayuda con un aspecto en particular que no sea tu especialidad. Si es así, intente contratar a uno de los desarrolladores de aplicaciones expertos en Envato Studio para completar el trabajo de forma rápida y confiable.