In this article, we will be building a Motion Sensor Testing App Project using Java and XML in Android. The application will be using the hardware of the device to detect the movements. The components required to detect the motion are Accelerometer and Gyroscope. The Accelerometer is an electronic sensor used to detect the device’s position in space by measuring its acceleration and movement. Whereas Gyroscope senses the angular movement of the device. In this app, we will observe a change in the screen’s color as we move the device. There will be a single activity in this application.
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Before going to the coding section first you have to do some pre-task
Add features in AndroidMainfest.xml: We need to add the requirement of hardware needed by this application. The two components that we require are Gyroscope and Accelerometer. Add these following into your AndroidMainfest.xml file.
<uses-feature android:name=”android.hardware.sensor.accelerometer” android:required=”true”/>
<uses-feature android:name=”android.hardware.sensor.gyroscope” android:required=”true”/>
Create two Java classes for Accelerometer and Gyroscope and name the class as Accelerometer and Gyroscope.
Change the style to NoActionBar in the themes.xml file:
<style name=”AppTheme” parent=”Theme.AppCompat.NoActionBar”>
Step 3: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < androidx.constraintlayout.widget.ConstraintLayout android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Lazyroar" android:textColor = "#0F9D58" android:textSize = "42dp" android:textStyle = "bold" app:layout_constraintBottom_toBottomOf = "parent" app:layout_constraintLeft_toLeftOf = "parent" app:layout_constraintRight_toRightOf = "parent" app:layout_constraintTop_toTopOf = "parent" /> </ androidx.constraintlayout.widget.ConstraintLayout > |
Step 4: Working with the Accelerometer.java file
In the Accelerometer.java file, we will create functions to get the device’s coordinates in the X, Y, and Z-axis. The function will send the required parameters to the Sensor and will get the coordinates in the return value. We will first create SensorManager, Sensor, and SensorEventListener objects. SensorManager and Sensor variables allow us to access the device’s sensors whereas SensorEventListener is called every time the device’s position changes and sensors are engaged. Below is the code for the Accelerometer.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; public class Accelerometer { // create an interface with one method public interface Listener { // create method with all 3 // axis translation as argument void onTranslation( float tx, float ty, float ts); } // create an instance private Listener listener; // method to set the instance public void setListener(Listener l) { listener = l; } private SensorManager sensorManager; private Sensor sensor; private SensorEventListener sensorEventListener; // create constructor with // context as argument Accelerometer(Context context) { // create instance of sensor manager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); // create instance of sensor // with type linear acceleration sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); // create the sensor listener sensorEventListener = new SensorEventListener() { // this method is called when the // device's position changes @Override public void onSensorChanged(SensorEvent sensorEvent) { // check if listener is // different from null if (listener != null ) { // pass the three floats in listener on translation of axis listener.onTranslation(sensorEvent.values[ 0 ], sensorEvent.values[ 1 ], sensorEvent.values[ 2 ]); } } @Override public void onAccuracyChanged(Sensor sensor, int i) { } }; } // create register method // for sensor notifications public void register() { // call sensor manger's register listener // and pass the required arguments sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } // create method to unregister // from sensor notifications public void unregister() { // call sensor manger's unregister listener // and pass the required arguments sensorManager.unregisterListener(sensorEventListener); } } |
Step 4: Working with the Gyroscope.java file
In the Gyroscope.java file, everything will be the same except the sensor will be of type gyroscope and not accelerometer. Also, the listener will be on rotation instead of translation. Below is the code for the Gyroscope.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; public class Gyroscope { // create an interface with one method public interface Listener { // create method with all 3 // axis translation as argument void onRotation( float tx, float ty, float ts); } // create an instance private Listener listener; // method to set the instance public void setListener(Listener l) { listener = l; } private SensorManager sensorManager; private Sensor sensor; private SensorEventListener sensorEventListener; // create constructor with context as argument Gyroscope(Context context) { // create instance of sensor manager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); // create instance of sensor with type gyroscope sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); // create the sensor listener sensorEventListener = new SensorEventListener() { // this method is called when // the device's position changes @Override public void onSensorChanged(SensorEvent sensorEvent) { // check if listener is different from null if (listener != null ) { // pass the three floats in listener on rotation of axis listener.onRotation(sensorEvent.values[ 0 ], sensorEvent.values[ 1 ], sensorEvent.values[ 2 ]); } } @Override public void onAccuracyChanged(Sensor sensor, int i) { } }; } // create register method // for sensor notifications public void register() { // call sensor manager's register listener and pass the required arguments sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } // create method to unregister // from sensor notifications public void unregister() { // call sensor manager's unregister listener // and pass the required arguments sensorManager.unregisterListener(sensorEventListener); } } |
Step 5: Working with the MainActivity.java file
In the MainActivity.java file, we will create listener functions of both classes. We will set the background color of the screen on the device’s rotation or movement. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.graphics.Color; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { // create variables of the two class private Accelerometer accelerometer; private Gyroscope gyroscope; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); // instantiate them with this as context accelerometer = new Accelerometer( this ); gyroscope = new Gyroscope( this ); // create a listener for accelerometer accelerometer.setListener( new Accelerometer.Listener() { //on translation method of accelerometer @Override public void onTranslation( float tx, float ty, float ts) { // set the color red if the device moves in positive x axis if (tx > 1 .0f) { getWindow().getDecorView().setBackgroundColor(Color.RED); } // set the color blue if the device moves in negative x axis else if (tx < - 1 .0f) { getWindow().getDecorView().setBackgroundColor(Color.BLUE); } } }); // create a listener for gyroscope gyroscope.setListener( new Gyroscope.Listener() { // on rotation method of gyroscope @Override public void onRotation( float rx, float ry, float rz) { // set the color green if the device rotates on positive z axis if (rz > 1 .0f) { getWindow().getDecorView().setBackgroundColor(Color.GREEN); } // set the color yellow if the device rotates on positive z axis else if (rz < - 1 .0f) { getWindow().getDecorView().setBackgroundColor(Color.YELLOW); } } }); } // create on resume method @Override protected void onResume() { super .onResume(); // this will send notification to // both the sensors to register accelerometer.register(); gyroscope.register(); } // create on pause method @Override protected void onPause() { super .onPause(); // this will send notification in // both the sensors to unregister accelerometer.unregister(); gyroscope.unregister(); } } |