Verwenden des Beschleunigungsmessers unter Android

In diesem Lernprogramm werden wir untersuchen, wie der Beschleunigungssensor, einer der vielen Hardwaresensoren moderner Smartphones, in einer Android-Anwendung verwendet wird. Ich werde erklären, was ein Beschleunigungssensor ist und warum es etwas ist, das Sie in Ihren Android-Anwendungen nutzen möchten.

Einführung

Vor den Anfängen von Smartphones war eine der wenigen Hardwarekomponenten, mit denen Anwendungen interagieren konnten, die Tastatur. Aber die Zeiten haben sich geändert und die Interaktion mit Hardwarekomponenten wird immer häufiger.

Die Verwendung von Gesten wirkt oft natürlicher als die Interaktion mit der Benutzeroberfläche über Maus und Tastatur. Dies gilt insbesondere für Touch-Geräte wie Smartphones und Tablets. Ich finde, dass die Verwendung von Gesten eine Android-Anwendung zum Leben erwecken kann, was sie für den Benutzer interessanter und aufregender macht.

Viele Apps nutzen jetzt den Beschleunigungssensor. Schauen Sie sich zum Beispiel diese App-Vorlagen auf dem Envato Market an, zu denen ein Speed-Rennspiel und ein Zufallszahlenschüttler gehören.

In diesem Lernprogramm verwenden wir eine Geste, die Sie in vielen mobilen Anwendungen finden, die Shake-Geste. Wir verwenden die Shake-Geste, um zufällig sechs Lotterie-Nummern zu generieren und sie mit einer hübschen Animation auf dem Bildschirm anzuzeigen.

1. Erste Schritte

Schritt 1: Projekt einrichten

Starten Sie ein neues Android-Projekt in Ihrer bevorzugten IDE (Integrated Development Environment) für Android-Entwicklung. Für dieses Tutorial verwende ich IntelliJ IDEA.

Wenn Ihre IDE die Android-Entwicklung unterstützt, wurde eine erstellt Main Klasse für dich. Der Name dieser Klasse kann je nach verwendeter IDE variieren. Das Main Die Klasse spielt eine wichtige Rolle, wenn Ihre Anwendung gestartet wird. Ihre IDE sollte auch eine Hauptlayoutdatei erstellt haben, die die Main Klasse verwendet, um die Benutzeroberfläche der Anwendung zu erstellen.

Da wir eine Schüttelbewegung verwenden, ist es eine gute Idee, die Ausrichtung des Geräts zu sperren. Dadurch wird sichergestellt, dass die Benutzeroberfläche der Anwendung nicht ständig zwischen Hoch- und Querformat wechselt. Öffnen Sie die Manifestdatei des Projekts und legen Sie das fest Bildschirmausrichtung Option zu Porträt.

     

Schritt 2: Einrichten des Sensors

Nachdem unser Projekt eingerichtet wurde, ist es an der Zeit, uns die Hände schmutzig zu machen und Code zu schreiben. Im Moment hat die Hauptaktivitätsklasse eine onCreate Methode, in der wir das Hauptlayout durch Aufrufen festlegen setContentView Wie nachfolgend dargestellt.

public class Main erweitert Aktivität / ** Wird beim ersten Erstellen der Aktivität aufgerufen. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); 

Abhängig von der verwendeten IDE müssen Sie möglicherweise einige Importanweisungen hinzufügen Main.java, die Datei, in der Ihr Main Klasse lebt. Die meisten IDEs fügen diese Importanweisungen für Sie ein, aber ich möchte sicherstellen, dass wir uns auf derselben Seite befinden, bevor wir fortfahren. Die erste Importanweisung, import android.app.Activity, importiert die Aktivität Klasse, während die zweite Importanweisung, import android.os.Bundle, importiert die Bündeln Klasse. Die dritte Importanweisung, com.example.R, enthält die Definitionen für die Ressourcen der Anwendung. Diese Importanweisung unterscheidet sich von der unten gezeigten, da sie vom Namen Ihres Pakets abhängt.

import android.app.Activity; import android.os.Bundle; import com.example.R;

Im nächsten Schritt werden wir das nutzen SensorEventListener Schnittstelle, die im Android SDK deklariert ist. Um die SensorEventListener Schnittstelle, die Main Die Aktivitätsklasse muss wie im folgenden Codeausschnitt implementiert implementiert werden. Wenn Sie sich das Update ansehen Main Aktivitätskurs, Sie werden feststellen, dass ich die implementiert Schlüsselwort, um dem Compiler zu sagen, dass das Main Klasse implementiert die SensorEventListener Schnittstelle.

public class Main erweitert Activity implementiert SensorEventListener / ** Wird beim ersten Erstellen der Aktivität aufgerufen. * / @Override public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.main); 

Um die SensorEventListener Schnittstelle müssen Sie eine weitere Importanweisung hinzufügen (siehe unten). Die meisten IDEs fügen die Import-Anweisung intelligent für Sie hinzu, sodass Sie sich wahrscheinlich keine Gedanken darüber machen müssen.

import android.hardware.SensorEventListener;

Von dem Moment an aktualisieren Sie die Main Bei der Klassenimplementierung werden, wie oben gezeigt, einige Fehler angezeigt. Dies ist nicht überraschend, da zwei Methoden benötigt werden, um die SensorEventListener Schnittstelle.

Wenn Sie IntelliJ IDEA verwenden, sollten Sie aufgefordert werden, diese erforderlichen Methoden hinzuzufügen, wenn Sie auf den Fehler klicken. Wenn Sie eine andere IDE verwenden, kann dieses Verhalten anders sein. Fügen Sie die beiden erforderlichen Methoden manuell hinzu, wie im nachstehenden Code-Snippet gezeigt. Stellen Sie sicher, dass Sie diese Methoden in der Main Klasse und außerhalb der onCreate Methode.

@Override public void onSensorChanged (Ereignis SensorEvent)  @Override public void onAccuracyChanged (Sensorsensor, int. Genauigkeit) 

Werfen wir einen Blick auf die onSensorChanged Methode. Wir werden diese Methode verwenden, um die Verwacklungsgeste zu erkennen. Das onSensorChanged Diese Methode wird jedes Mal aufgerufen, wenn der eingebaute Sensor eine Änderung feststellt. Diese Methode wird immer dann aufgerufen, wenn sich das Gerät in Bewegung befindet. Um die Sensor und SensorEvent Klassen fügen wir zwei zusätzliche Importanweisungen hinzu (siehe unten).

importieren android.hardware.Sensor; import android.hardware.SensorEvent;

Bevor wir implementieren onSensorChanged, Wir müssen zwei private Variablen in der deklarieren Main Klasse, senSensorManager vom Typ SensorManager und senAccelerometer vom Typ Sensor.

privater SensorManager senSensorManager; privater Sensor senAccelerometer;

Das SensorManager Klasse wird in deklariert android.hardware.SensorManager. Wenn Fehler auftauchen, überprüfen Sie das SensorManager Klasse wird auch importiert.

importieren android.hardware.SensorManager;

In dem onCreate Methode initialisieren wir die soeben deklarierten Variablen und registrieren einen Listener. Schauen Sie sich die aktualisierte Implementierung des onCreate Methode.

@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 (dies senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 

Zu initialisieren SensorManager Wir rufen zum Beispiel an getSystemService das System holen SensorManager Beispiel, mit dem wir wiederum auf die Sensoren des Systems zugreifen. Das getSystemService Diese Methode wird verwendet, um einen Verweis auf einen Dienst des Systems abzurufen, indem der Name des Dienstes übergeben wird. Mit dem verfügbaren Sensor-Manager erhalten wir durch Aufrufen einen Hinweis auf den Beschleunigungssensor des Systems getDefaultSensor Auf dem Sensor-Manager und übergeben Sie den Sensortyp, an dem wir interessiert sind. Wir registrieren den Sensor dann mit einem der SensorManageröffentliche Methoden, registerListener. Diese Methode akzeptiert drei Argumente, den Kontext der Aktivität, einen Sensor und die Rate, mit der Sensorereignisse an uns übermittelt werden.

public class Main erweitert Activity implementiert SensorEventListener private SensorManager senSensorManager; privater Sensor senAccelerometer; /** Wird aufgerufen, wenn die Aktivität erstellt wird. * / @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 (dies senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);  @Override public void onSensorChanged (SensorEvent sensorEvent)  @Override public void onAccuracyChanged (Sensorsensor, int. Genauigkeit) 

Es gibt zwei weitere Methoden, die wir überschreiben müssen, onPause und auf Wiederaufnahme. Dies sind Methoden der Main Klasse. Es ist empfehlenswert, die Registrierung des Sensors aufzuheben, wenn sich die Anwendung im Ruhezustand befindet, und den Sensor erneut zu registrieren, wenn die Anwendung wieder aufgenommen wird. Werfen Sie einen Blick auf die folgenden Codeausschnitte, um zu erfahren, wie dies in der Praxis funktioniert.

protected void onPause () super.onPause (); senSensorManager.unregisterListener (this); 
protected void onResume () super.onResume (); senSensorManager.registerListener (dies senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 

Schritt 3: Erkennen der Shake-Geste

Wir können uns nun auf das Fleisch der Anwendung konzentrieren. Es ist ein bisschen mathematisch, um herauszufinden, wann eine Schüttelbewegung stattfindet. Der größte Teil der Logik wird in die onSensorChanged Methode. Wir beginnen damit, einige Variablen in unserem zu deklarieren Main Klasse. Sehen Sie sich den Code-Ausschnitt unten an.

private long lastUpdate = 0; privates Float last_x, last_y, last_z; privates statisches Finale int SHAKE_THRESHOLD = 600;

Lassen Sie uns nun die Implementierung der onSensorChanged Methode. Wir greifen einen Hinweis auf die Sensor Instanz mit der SensorEvent Instanz, die uns übergeben wird. Wie Sie im Code-Snippet unten sehen können, überprüfen wir noch einmal, ob wir einen Verweis auf den richtigen Sensortyp, den Beschleunigungssensor des Systems, erhalten.

public void onSensorChange (SensorEvent sensorEvent) Sensor mySensor = sensorEvent.sensor; if (mySensor.getType () == Sensor.TYPE_ACCELEROMETER) 

Im nächsten Schritt wird die Position des Geräts im Weltraum ermittelt x, y, und z Achse. Sehen Sie sich das Bild unten an, um besser zu verstehen, worauf ich mich beziehe. Das x Achse definiert die seitliche Bewegung, während die y Achse definiert die vertikale Bewegung. Das z Achse ist etwas kniffliger, da sie die Bewegung in und aus der durch die Ebene definierten Ebene definiert x und y Achsen.


Um die Werte jeder Achse zu erhalten, fragen wir das Sensorereignis nach seinen Werten (siehe unten). Die Ereignisse Werte Attribut ist ein Array von Floats.

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]; 

Die Sensoren des Systems sind unglaublich empfindlich. Wenn Sie ein Gerät in der Hand halten, ist es ständig in Bewegung, unabhängig davon, wie ruhig Ihre Hand ist. Das Ergebnis ist, dass die onSensorChanged Methode wird mehrmals pro Sekunde aufgerufen. Wir brauchen nicht all diese Daten, daher müssen wir sicherstellen, dass wir nur eine Teilmenge der Daten prüfen, die wir vom Beschleunigungssensor des Geräts erhalten. Wir speichern die aktuelle Zeit (in Millisekunden) des Systems in curTime und prüfen, ob mehr als 100 Millisekunden sind seit dem letzten Mal vergangen onSensorChanged wurde angerufen.

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; 

Das letzte Puzzleteil erkennt, ob das Gerät geschüttelt wurde oder nicht. Wir nehmen das Mathematik Klasse, um die Geschwindigkeit des Geräts wie unten gezeigt zu berechnen. Die statisch erklärt SHAKE_THRESHOLD Variable wird verwendet, um zu sehen, ob eine Shake-Geste erkannt wurde oder nicht. Ändern SHAKE_THRESHOLD Erhöht oder verringert die Empfindlichkeit, sodass Sie mit dem Wert frei spielen können.

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; Flottgeschwindigkeit = Math.abs (x + y + z - last_x - last_y - last_z) / diffTime * 10000; if (Geschwindigkeit> SHAKE_THRESHOLD)  last_x = x; last_y = y; last_z = z; 

2. Beenden der Lotterieanwendung

Wir haben jetzt eine Anwendung, die mit dem Beschleunigungssensor eine Verwacklungsgeste erkennen kann. Beenden Sie dieses Projekt mit der Shake-Geste, um sechs zufällige Lottozahlen auszuwählen. Ich zeige Ihnen, wie Sie eine Zufallszahl zwischen generieren 1 und 49, Es steht Ihnen jedoch frei, meine Implementierung so zu ändern, dass sie mit der Art und Weise, wie die Lotterie in Ihrem Land gespielt wird, funktioniert.

Beginnen wir mit dem Einrichten der Hauptlayoutdatei der Anwendung, die wir für die Benutzeroberfläche verwenden. Wie Sie unten sehen können, verwende ich sechs Rahmenlayouts mit dem Hintergrund eines Ballbildes.

                        

Jedes Rahmenlayout enthält eine Textansicht, in der eine zufällig generierte Lotterienummer angezeigt wird. Beachten Sie, dass jedes Frame-Layout und jede Textansicht ein Ich würde um sicherzustellen, dass wir sie später referenzieren können.

Lassen Sie uns, nachdem das Hauptlayout einsatzbereit ist, die Main Klasse. Wir beginnen mit dem Erstellen getRandomNumber, eine private Methode zur Erzeugung von sechs Zufallszahlen zwischen 1 und 49.

private void getRandomNumber () ArrayList numbersGenerated = new ArrayList (); für (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--;   

Wir erstellen zuerst ein Anordnungsliste Beispiel, in dem wir die sechs Zahlen speichern. In jeder Schleife der zum Schleife nutzen wir Java Zufällig Klasse, um eine Zufallszahl zu generieren. Um sicher zu gehen, dass wir eine Nummer dazwischen bekommen 1 und 49, Wir fügen hinzu 1 zum Ergebnis Im nächsten Schritt prüfen Sie, ob die generierte Nummer bereits in der Array-Liste enthalten ist, da in der Array-Liste nur eindeutige Nummern gewünscht werden.

Beachten Sie, dass möglicherweise zwei weitere Importanweisungen hinzugefügt werden müssen, um den Compiler zufrieden zu stellen.

import java.util.ArrayList; import java.util.Random;

Der letzte Schritt ist die Anzeige der zufällig generierten Nummer in der Benutzeroberfläche. Wir erhalten einen Verweis auf die zuvor erstellten Textansichten und füllen jede Textansicht mit einer Zufallszahl. Wir fügen den Frame-Layouts auch eine hübsche Animation hinzu, können jedoch die Animation auslassen oder ändern.

private void getRandomNumber () ArrayList numbersGenerated = new ArrayList (); für (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); 

Wir müssen noch ein paar Import-Anweisungen hinzufügen, damit das funktioniert. Sehen Sie sich den Code-Ausschnitt unten an.

Import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.TextView;

Sehen Sie sich für die Animationen den Inhalt der Animationsdatei an. Beachten Sie, dass Sie ein erstellen müssen anim Ordner im Ressourcenverzeichnis Ihres Projekts und benennen Sie es move_down_ball_first.xml. Durch Anpassen der Werte von Rahmen Element können Sie die Dauer der Animation und die Position jedes Balls ändern.

   

Wir müssen nur noch anrufen getRandomNumber im onSensorChanged in dem Main Klasse. Sehen Sie sich die vollständige Implementierung von an onSensorChanged unten gezeigt.

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; Flottgeschwindigkeit = Math.abs (x + y + z - last_x - last_y - last_z) / diffTime * 10000; if (Geschwindigkeit> SHAKE_THRESHOLD) getRandomNumber ();  last_x = x; last_y = y; last_z = z; 

Fazit

In diesem Tutorial habe ich Ihnen gezeigt, wie der Beschleunigungssensor funktioniert und wie Sie ihn verwenden können, um eine Schüttelbewegung zu erkennen. Natürlich gibt es viele andere Anwendungsfälle für den Beschleunigungsmesser. Grundkenntnisse über das Erkennen von Gesten mithilfe des Beschleunigungssensors ermutigen Sie dazu, mit dem Beschleunigungssensor zu experimentieren, um zu sehen, was Sie sonst noch damit machen können.

Wenn Sie viel mit Android-Entwicklung arbeiten, werden Sie wahrscheinlich auf Situationen stoßen, in denen Sie Hilfe zu einem bestimmten Aspekt benötigen, der nicht Ihre Spezialität ist. Wenn ja, versuchen Sie, einen der erfahrenen App-Entwickler bei Envato Studio einzustellen, um die Arbeit schnell und zuverlässig abzuschließen.