This video shows the steps to develop your Inclinometer Android app to measure tilt angle at a precision of 0.01 degrees.
The App is published in Google’s play store and can be accessed at:
https://play.google.com/store/apps/details?id=com.programmerworld.inclinometer_measuretilt
I hope you like this video. For any questions, suggestions or appreciation please contact us at: https://programmerworld.co/contact/ or email at: programmerworld1990@gmail.com
Complete source code and other details:
package com.programmerworld.inclinometer_measuretilt;
import android.content.pm.ActivityInfo;
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.ToggleButton;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
private TextView textViewOutput;
private ToggleButton toggleButton;
private SensorManager sensorManager;
private Sensor sensorAccelerometer, sensorMagneticField;
private float[] floatGravity = new float[3];
private float[] floatGeoMagnetic = new float[3];
private float[] floatOrientationAngles = new float[3]; // 0 = Z, 1 = X and 2 = Y
private float[] floatOrientationAnglesDisplay = {0.0f,0.0f,0.0f};
private float[] floatRotationMatrix = new float[9];
private float[] floatInclinationMatrix = new float[9];
private double SENSITIVITY = 0.01; // lower this number higher will be the sensitivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
textViewOutput = findViewById(R.id.textViewOutput);
toggleButton = findViewById(R.id.toggleButton2);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
SensorEventListener sensorEventListenerAccelerometer = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
floatGravity = event.values;
Display();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
SensorEventListener sensorEventListenerMagneticField = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
floatGeoMagnetic = event.values;
Display();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
sensorManager.registerListener(sensorEventListenerAccelerometer,
sensorAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(sensorEventListenerMagneticField,
sensorMagneticField, SensorManager.SENSOR_DELAY_FASTEST);
return insets;
});
}
private void Display(){
SensorManager.getRotationMatrix(floatRotationMatrix, floatInclinationMatrix,
floatGravity, floatGeoMagnetic);
SensorManager.getOrientation(floatRotationMatrix, floatOrientationAngles);
if (Math.abs(floatOrientationAnglesDisplay[1] - floatOrientationAngles[1]) > SENSITIVITY){
floatOrientationAnglesDisplay[1] = floatOrientationAngles[1];
floatOrientationAnglesDisplay[1] = (float) (floatOrientationAnglesDisplay[1]*180/Math.PI)*-1;
floatOrientationAnglesDisplay[1] = (float) (Math.round(floatOrientationAnglesDisplay[1] * 100)) / 100;
if (toggleButton.getText().equals("Pause")) {
textViewOutput.setText(String.valueOf(floatOrientationAnglesDisplay[1]));
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/programmerworld_foreground"
android:label="@string/app_name"
android:roundIcon="@mipmap/programmerworld_round"
android:supportsRtl="true"
android:theme="@style/Theme.InclinometerMeasureTilt"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textViewOutput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:text="0"
android:textSize="60sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<ImageView
android:id="@+id/imageView"
android:layout_width="178dp"
android:layout_height="169dp"
android:layout_marginTop="25dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/programmerworld_round" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:text="o"
android:textSize="34sp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/textViewOutput"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<ToggleButton
android:id="@+id/toggleButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:text="ToggleButton"
android:textOff="Pause"
android:textOn="Resume"
android:textSize="34sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewOutput" />
</androidx.constraintlayout.widget.ConstraintLayout>
Screenshots:
![](https://programmerworld.co/wp-content/uploads/2024/04/image-39.png)
![](https://programmerworld.co/wp-content/uploads/2024/04/image-40.png)
![](https://programmerworld.co/wp-content/uploads/2024/04/image-41.png)
![](https://programmerworld.co/wp-content/uploads/2024/04/image-42.png)
Project Folder: Complete project folder can be accessed at the below link on payment of USD 9.
Payment: Inclinometer App
https://drive.google.com/file/d/10ZlZ_WbAb7No4kIinkYfnk-HZ8DTnQMq/view?usp=drive_link
Excerpt:
The provided code and details demonstrate the development of an Inclinometer Android app for measuring tilt angles with precision. The app utilizes sensors, including accelerometer and magnetic field sensors, to calculate orientation angles and display the tilt angle. Users can toggle between pause and resume options. The XML files define the app’s layout and permissions, while screenshots showcase the app’s interface. The complete project folder is available for purchase, and a drive link for the project is provided.