En este tutorial, vamos a explorar cómo utilizar el acelerómetro, uno de los muchos sensores
de hardware de los teléfonos inteligentes modernos, en una aplicación Android. Voy a explicar
lo que es un acelerómetro y por las que puede ser algo que usted quiere tomar ventaja de
Android en sus aplicaciones.
Introducción
Antes del amanecer de los teléfonos inteligentes, uno de los componentes de hardware pocas
aplicaciones podrían tener interacciones con el teclado era. Pero los tiempos han cambiado y
la interacción con los componentes de hardware se está volviendo más y más común.
Utilizando gestos a menudo se siente más natural de interactuar con una interfaz de usuario a
través del ratón y el teclado. Esto es especialmente cierto para los dispositivos táctiles, como
los teléfonos inteligentes y tabletas. Me parece que el uso de gestos puede aportar una
aplicación Android a la vida, por lo que es más interesante y emocionante para el usuario.
Un buen número de aplicaciones están ahora haciendo uso del acelerómetro. Por ejemplo,
echar un vistazo a estas plantillas de aplicaciones en Envato mercado, que incluyen un juego
de carreras de velocidad y un número al azar agitador.
En este tutorial, vamos a utilizar un gesto que se encuentran en un buen número de
aplicaciones móviles, el gesto de agitar. Vamos a utilizar la función de agitar para generar
aleatoriamente seis números de la lotería y mostrarlos en la pantalla mediante una animación
bastante.
1. Introducción
Paso 1: Configuración del Proyecto
Iniciar un nuevo proyecto Android en su IDE favorito (Integrated Development Environment)
para el desarrollo de Android. Para este tutorial, voy a estar usando IntelliJ IDEA.
Si el IDE es compatible con el desarrollo de Android, que va a haber creado una clase principal
para usted. El nombre de esta clase puede variar dependiendo de la IDE que está utilizando. La
clase principal juega un papel clave cuando se inicia la aplicación. El IDE también debe haber
creado un archivo de diseño principal que utiliza la clase principal para crear la interfaz de
usuario de la aplicación.
Puesto que vamos a hacer uso de un gesto de agitar, que es una buena idea para bloquear la
orientación del dispositivo. Esto asegurará que la interfaz de usuario de la aplicación no está
cambiando constantemente entre el retrato y el paisaje. Abrir archivo de manifiesto del
proyecto y establecer la opción screenOrientation a vertical.
<Actividad android: name = "[Link]"
android: screenOrientation = "retrato"
android: label = "@ string / nombre_apl">
<Intención de filtro>
<Acción android: name = "[Link]" />
<Categoría android: name = "[Link]" />
</ Intención de filtro>
</ Actividad>
Paso 2: Configuración del sensor
Con nuestro proyecto establecido, es hora de poner las manos sucias y escribir algo de código.
Por el momento, la clase principal actividad tiene un método onCreate en el que nos fijamos el
diseño principal invocando setContentView como se muestra a continuación.
8
9
public class principal se extiende Actividad {
/** Se llama cuando se crea por primera vez la actividad. * /
@Anular
public void onCreate (Bundle savedInstanceState) {
[Link] (savedInstanceState);
setContentView ([Link]);
}
Dependiendo de la IDE que está utilizando, puede que tenga que añadir unas declaraciones de
importación a [Link], el archivo en el que vive la clase principal. La mayoría de los entornos
de desarrollo se inserte estas declaraciones de importación para usted, pero yo quiero para
asegurarse de que estamos en la misma página antes de continuar. La primera declaración de
importación, importación [Link], importa la clase de actividad, mientras que la
segunda declaración de importación, importación [Link], importa la clase Bundle.
La tercera declaración de importación, [Link].R, contiene las definiciones de los
recursos de la aplicación. Esta declaración de importación será diferente de la que aparece a
continuación, ya que depende del nombre de su paquete.
[Link] importación;
[Link] importación;
[Link].R importación;
En el siguiente paso, vamos a apalancar la interfaz SensorEventListener, que se declara en el
SDK de Android. Para utilizar la interfaz SensorEventListener, la clase Actividad principal
necesita para ponerlo en práctica, como se muestra en el siguiente fragmento de código. Si se
echa un vistazo a la clase de actividad principal actualizado, encontrará que utilizo la palabra
clave implementos para decirle al compilador que la clase implementa la interfaz principal
SensorEventListener.
3
4
clase pública se extiende la actividad principal implementa SensorEventListener {
/** Se llama cuando se crea por primera vez la actividad. * /
@Anular
public void onCreate (Bundle savedInstanceState) {
[Link] (savedInstanceState);
setContentView ([Link]);
}
Para utilizar la interfaz SensorEventListener, es necesario agregar otra declaración de
importación, como se muestra a continuación. La mayoría de los entornos de desarrollo
sumará de manera inteligente la declaración de importación para usted por lo que
probablemente no tendrá que preocuparse por esto.
[Link] importación;
A partir de este momento, se actualiza la implementación de la clase principal como se
muestra arriba, verá algunos errores pop-up. Esto no es sorprendente ya que necesitamos dos
implementar dos métodos necesarios de la interfaz SensorEventListener.
Si está utilizando IntelliJ IDEA, se le debería pedir al agregar estos métodos requeridos al hacer
clic en el error. Si estás utilizando un IDE diferente, este comportamiento puede ser diferente.
Vamos a añadir los dos métodos requeridos por la mano como se muestra en el fragmento de
código a continuación. Asegúrese de añadir estos métodos en la clase principal y fuera del
método onCreate.
2
3
@Anular
public void onSensorChanged (evento SensorEvent) {
@Anular
public void onAccuracyChanged (sensor del sensor, int exactitud) {
Vamos a echar un vistazo a el método onSensorChanged. Vamos a utilizar este método para
detectar el gesto de agitar. El método onSensorChanged se invoca cada vez que el sensor
integrado detecta un cambio. Este método se invoca repetidamente cada vez que el
dispositivo está en movimiento. Para utilizar el sensor y clases SensorEvent, añadimos dos
declaraciones de importación adicionales, como se muestra a continuación.
[Link] importación;
[Link] importación;
Antes de implementar onSensorChanged, tenemos que declarar dos variables privadas de la
clase principal, senSensorManager de tipo SensorManager y senAccelerometer del tipo de
sensor.
senSensorManager SensorManager privada;
senAccelerometer sensor privada;
La clase SensorManager se declara en [Link]. Si aparece cualquier
error de pop-up, compruebe que la clase SensorManager se importa también.
[Link] importación;
En el método onCreate, inicializamos las variables que acabamos declarado y se registra un
oyente. Echar un vistazo a la aplicación actualizada del método onCreate.
@Anular
protected void onCreate (Bundle savedInstanceState) {
[Link] (savedInstanceState);
setContentView ([Link].activity_main);
senSensorManager = (SensorManager) getSystemService (Context.SENSOR_SERVICE);
senAccelerometer = [Link] (Sensor.TYPE_ACCELEROMETER);
[Link] (esto, senAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
Para inicializar la instancia SensorManager, invocamos a buscar getSystemService ejemplo
SensorManager del sistema, que a su vez está en uso para acceder a los sensores del sistema.
El método getSystemService se utiliza para obtener una referencia a un servicio del sistema
pasando el nombre del servicio. Con el administrador del sensor a nuestra disposición,
obtenemos una referencia al acelerómetro del sistema invocando getDefaultSensor en el
gestor de sensor y pasando el tipo de sensor que nos interesa. A continuación, se registra el
sensor usando uno de los métodos públicos del SensorManager, registerListener. Este método
acepta tres argumentos, el contexto de la actividad, un sensor, y la velocidad a la que los
eventos de sensor se entregan a nosotros.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
clase pública se extiende la actividad principal implementa SensorEventListener {
senSensorManager SensorManager privada;
senAccelerometer sensor privada;
/** Se llama cuando se crea por primera vez la actividad. * /
@Anular
public void onCreate (Bundle savedInstanceState) {
[Link] (savedInstanceState);
setContentView ([Link]);
senSensorManager = (SensorManager) getSystemService (Context.SENSOR_SERVICE);
senAccelerometer = [Link]
(Sensor.TYPE_ACCELEROMETER);
[Link] (esto, senAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Anular
onSensorChanged public void (SensorEvent sensorEvent) {
}
@Anular
public void onAccuracyChanged (sensor del sensor, int exactitud) {
}
Hay otros dos métodos que tenemos que sobreescribir, onPause y onResume. Estos son
métodos de la clase principal. Es una buena práctica para anular el registro del sensor cuando
la aplicación hiberna y registrar el sensor de nuevo cuando la aplicación se reanuda. Echar un
vistazo a los fragmentos de código a continuación para tener una idea de cómo funciona esto
en la práctica.
protegida onPause void () {
[Link] ();
[Link] (this);
protegida onResume void () {
[Link] ();
[Link] (esto, senAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
Paso 3: detección de la función de agitar
Ahora podemos empezar a centrarse en la carne de la aplicación. Se requiere un poco de
matemáticas para averiguar cuando un gesto de agitar lleva a cabo. La mayor parte de la lógica
voy a entrar en el método onSensorChanged. Comenzamos declarando unas pocas variables
en nuestra clase principal. Echar un vistazo a el fragmento de código a continuación.
larga lastUpdate privada = 0;
last_x flotador privada, last_y, last_z;
privado static final int SHAKE_THRESHOLD = 600;
Ahora vamos a acercar sobre la aplicación del método onSensorChanged. Cogemos una
referencia a la instancia del sensor mediante la instancia SensorEvent que se pasa a nosotros.
Como se puede ver en el siguiente fragmento de código, que vuelva a comprobar que tenemos
una referencia al tipo de sensor correcto, el acelerómetro del sistema.
5
6
public void onSensorChange (SensorEvent sensorEvent) {
Sensor mySensor = [Link];
si ([Link] () == Sensor.TYPE_ACCELEROMETER) {
}
El siguiente paso es extraer la posición del dispositivo en el espacio, las x, y, y eje z. Echar un
vistazo a la siguiente imagen para entender mejor lo que me refiero. El eje x define el
movimiento lateral, mientras que el eje y define el movimiento vertical. El eje z es poco más
difícil, ya que define el movimiento dentro y fuera del plano definido por los ejes x e y.
Para obtener los valores de cada eje, nos preguntamos el caso del sensor por sus valores como
se muestra a continuación. Los valores de atributo del evento es una serie de flotadores.
public void onSensorChange (SensorEvent sensorEvent) {
Sensor mySensor = [Link];
si ([Link] () == Sensor.TYPE_ACCELEROMETER) {
float x = [Link] [0];
flotar y = [Link] [1];
flotar z = [Link] [2];
}
los sensores del sistema son increíblemente sensibles. Cuando la celebración de un dispositivo
en la mano, que está en constante movimiento, no importa cuán estable es la mano. El
resultado es que el método onSensorChanged se invoca varias veces por segundo. No
necesitamos todos estos datos por lo que necesitamos para asegurarse de que única muestra
un subconjunto de los datos que obtenemos de acelerómetro del dispositivo. Almacenamos la
hora actual del sistema (en milisegundos) almacenarlo en CURTIME y comprobar si hay más de
100 milisegundos han pasado desde la última vez que se invocó onSensorChanged.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
public void onSensorChange (SensorEvent sensorEvent) {
Sensor mySensor = [Link];
si ([Link] () == Sensor.TYPE_ACCELEROMETER) {
float x = [Link] [0];
flotar y = [Link] [1];
flotar z = [Link] [2];
larga CURTIME = [Link] ();
if ((CURTIME - lastUpdate)> 100) {
larga difftime = (CURTIME - lastUpdate);
lastUpdate = CURTIME;
}
}
La pieza final del rompecabezas es detectar si el dispositivo ha sido sacudida o no. Usamos la
clase de matemáticas para calcular la velocidad del dispositivo como se muestra a
continuación. La variable SHAKE_THRESHOLD estáticamente declarado se utiliza para ver si un
gesto de agitar se ha detectado o no. La modificación de los aumentos o disminuciones
SHAKE_THRESHOLD la sensibilidad por lo que no dude en jugar con su valor.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
public void onSensorChange (SensorEvent sensorEvent) {
Sensor mySensor = [Link];
si ([Link] () == Sensor.TYPE_ACCELEROMETER) {
float x = [Link] [0];
flotar y = [Link] [1];
flotar z = [Link] [2];
larga CURTIME = [Link] ();
if ((CURTIME - lastUpdate)> 100) {
larga difftime = (CURTIME - lastUpdate);
lastUpdate = CURTIME;
la velocidad de flotación = [Link] (x + y + z - last_x - last_y - last_z) / difftime * 10000;
si (velocidad> SHAKE_THRESHOLD) {
}
last_x = x;
last_y = y;
last_z = z;
}
}
2. Finalización de la aplicación de la lotería
Ahora tenemos una aplicación que puede detectar un gesto de agitar utilizando el
acelerómetro. Vamos a terminar este proyecto mediante el uso de la función de agitar a
recoger seis números de la lotería al azar. Te voy a mostrar cómo generar un número aleatorio
entre 1 y 49, pero que son libres de modificar mi aplicación para que funcione con cómo se
juega a la lotería en su país.
Vamos a empezar por la creación de archivo de diseño principal de la aplicación que vamos a
utilizar para la interfaz de usuario. Como se puede ver a continuación, utilizo seis diseños de
marco con un fondo de una imagen de una pelota.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
<? Xml version = "1.0" encoding = "UTF-8"?>
<LinearLayout xmlns: android = "[Link]
android: orientation = "vertical"
android: layout_width = "fill_parent"
android: layout_height = "fill_parent">
<LinearLayout
android: layout_height = "wrap_content"
android: layout_width = "fill_parent"
android: weightSum = "6"
android: orientation = "horizontal">
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: layout_weight = "2"
android: id = "@ + / Identificación del ball_1"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del número_1"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: layout_weight = "2"
android: id = "@ + / Identificación del ball_2"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del número_2"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: layout_weight = "2"
android: id = "@ + / Identificación del ball_3"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del NUMBER_3"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
</ LinearLayout>
<LinearLayout
android: layout_height = "wrap_content"
android: layout_width = "fill_parent"
android: weightSum = "6"
android: orientation = "horizontal">
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: layout_weight = "2"
android: id = "@ + / Identificación del ball_4"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del number_4"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: id = "@ + / Identificación del ball_5"
android: layout_weight = "2"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del number_5"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
<FrameLayout
android: layout_height = "wrap_content"
android: layout_width = "wrap_content"
android: layout_margin = "5 dp"
android: id = "@ + / Identificación del ball_6"
android: layout_weight = "2"
Android: Fondo = "@ dibujable / azul">
<TextView
android: layout_width = "fill_parent"
android: layout_height = "fill_parent"
android: id = "@ + / Identificación del number_6"
Android: la gravedad = "center"
android: layout_gravity = "center_vertical"
android: textColor = "@ android: el color / blanco" />
</ FrameLayout>
</ LinearLayout>
</ LinearLayout>
Cada diseño de marcos contiene una vista de texto que mostrará un número de lotería
generado aleatoriamente. Tenga en cuenta que cada disposición de marcos y ver el texto tiene
un ID para asegurarse de que podemos hacer referencia a ellos más tarde.
Con la disposición principal listo para usar, vamos a revisar la clase principal. Comenzamos
creando GetRandomNumber, un método privado para la generación de seis números
aleatorios entre 1 y 49.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
GetRandomNumber private void () {
ArrayList numbersGenerated = new ArrayList ();
for (int i = 0; i <6; i ++) {
Random randNumber = new Random ();
int iNumber = [Link] (48) + 1;
if (! [Link] (iNumber)) {
[Link] (iNumber);
} Else {
yo--;
}
}
Primero creamos una instancia ArrayList, que utilizamos para almacenar los seis números. En
cada bucle del bucle, nos aprovechamos de la clase aleatoria de Java para generar un número
aleatorio. Para asegurarse de que tenemos un número entre 1 y 49, se añade 1 al resultado. El
siguiente paso es comprobar si el número generado ya está en la lista de arreglo, porque sólo
queremos números únicos en la lista de arreglo.
Tenga en cuenta que puede ser necesario añadir dos más declaraciones de importación para
mantener el compilador feliz.
1
2
[Link] importación;
[Link] importación;
El paso final es para mostrar el número generado de forma aleatoria en la interfaz de usuario.
Obtenemos una referencia a la vista del texto que hemos creado antes y poblar cada vista de
texto con un número aleatorio. También vamos a añadir una animación ordenada para los
diseños de marco, pero no dude en omitir o modificar la animación.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
sesenta y cinco
66
67
68
69
70
71
72
73
74
75
GetRandomNumber private void () {
ArrayList numbersGenerated = new ArrayList ();
for (int i = 0; i <6; i ++) {
Random randNumber = new Random ();
int iNumber = [Link] (48) + 1;
if (! [Link] (iNumber)) {
[Link] (iNumber);
} Else {
yo--;
}
}
texto TextView = (TextView) findViewById ([Link].number_1);
[Link] ( "" + [Link] (0));
text = (TextView) findViewById ([Link].number_2);
[Link] ( "" + [Link] (1));
text = (TextView) findViewById ([Link].number_3);
[Link] ( "" + [Link] (2));
text = (TextView) findViewById ([Link].number_4);
[Link] ( "" + [Link] (3));
text = (TextView) findViewById ([Link].number_5);
[Link] ( "" + [Link] (4));
text = (TextView) findViewById ([Link].number_6);
[Link] ( "" + [Link] (5));
FrameLayout ball1 = (FrameLayout) findViewById ([Link].ball_1);
[Link] ([Link]);
FrameLayout ball2 = (FrameLayout) findViewById ([Link].ball_2);
[Link] ([Link]);
FrameLayout ball3 = (FrameLayout) findViewById ([Link].ball_3);
[Link] ([Link]);
FrameLayout ball4 = (FrameLayout) findViewById ([Link].ball_4);
[Link] ([Link]);
FrameLayout ball5 = (FrameLayout) findViewById ([Link].ball_5);
[Link] ([Link]);
FrameLayout ball6 = (FrameLayout) findViewById ([Link].ball_6);
[Link] ([Link]);
Animación a = [Link] (esto, [Link].move_down_ball_first);
[Link] ([Link]);
[Link] ();
[Link] (a);
[Link] ([Link]);
[Link] ();
[Link] (a);
[Link] ([Link]);
[Link] ();
[Link] (a);
[Link] ([Link]);
[Link] ();
[Link] (a);
[Link] ([Link]);
[Link] ();
[Link] (a);
[Link] ([Link]);
[Link] ();
[Link] (a);
Vamos a tener que añadir un poco más de las declaraciones de importación para hacer todo
este trabajo. Echar un vistazo a el fragmento de código a continuación.
[Link] importación;
[Link] importación;
[Link] de importación;
[Link] importación;
[Link] importación;
En cuanto a las animaciones, echar un vistazo a los contenidos del archivo de animación a
continuación. Tenga en cuenta que es necesario crear una carpeta en el directorio anim
recursos de su proyecto y el nombre de move_down_ball_first.xml. Mediante el ajuste de los
valores del elemento de escala, puede modificar la duración de la animación y la posición de
cada bola.
01
02
03
04
05
06
07
08
09
10
11
12
<? Xml version = "1.0" encoding = "UTF-8"?>
<Xmlns conjunto: androide = "[Link]
android: fillAfter = "true"
android: interpolador = "@ android: anim / bounce_interpolator">
<escala
android: duración = "1500"
android: fromXScale = "1.0"
android: fromYScale = "- 10.0"
android: toXScale = "1.0"
android: toYScale = "1.0" />
</ Set>
Todo lo que queda para nosotros que hacer es llamar GetRandomNumber en
onSensorChanged en la clase principal. Echar un vistazo a la implementación completa de
onSensorChanged se muestra a continuación.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
dieciséis
17
18
19
20
21
22
23
24
25
26
public void onSensorChange (SensorEvent sensorEvent) {
Sensor mySensor = [Link];
si ([Link] () == Sensor.TYPE_ACCELEROMETER) {
float x = [Link] [0];
flotar y = [Link] [1];
flotar z = [Link] [2];
larga CURTIME = [Link] ();
if ((CURTIME - lastUpdate)> 100) {
larga difftime = (CURTIME - lastUpdate);
lastUpdate = CURTIME;
la velocidad de flotación = [Link] (x + y + z - last_x - last_y - last_z) / difftime * 10000;
si (velocidad> SHAKE_THRESHOLD) {
GetRandomNumber ();
}
last_x = x;
last_y = y;
last_z = z;
}
}