Sensors Tutorial for Android: Getting Started
In this sensors tutorial, you’ll learn about different types of sensors and how to use sensor fusion (accelerometer with magnetometer) to develop a compass. By Aaqib Hussain.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Sensors Tutorial for Android: Getting Started
20 mins
- Getting Started
- Types of Sensors
- List of Sensors
- Combining Sensor Data With Sensor Fusion
- Setting up Sensors
- Getting Values From the Accelerometer and Magnetometer
- Calculating Orientation in onSensorChanged
- Adding Direction Based on Angle
- Sending Data to MainActivity
- Handling Events in the Background
- Where to Go From Here?
Apps use sensors to perform different tasks — in fact, most built-in features of your mobile phone depend on them. For example, touch sensors, proximity sensors, accelerometers, magnetometers and thermometers are all using underlying physical sensors built into a device.
Sensors let devices interact with their surroundings by providing data from a three-dimensional perspective based on the device’s position or motion, or by monitoring the environmental changes to a device’s surroundings.
Sensors are an essential part of every mobile device, improving the overall user experience. A variety of mobile games use sensors such as gyroscopes, accelerometers, and more, enabling users to have a more immersive experience.
In this tutorial, you’ll learn:
- How to use sensors.
- What sensor fusion is.
- What the different types of sensors are and how they work.
- How to use classes like
Sensor
,SensorManager
andSensorEventListener
, which facilitate interacting with sensors on Android devices.
You’ll put this knowledge to work by combining a magnetometer with an accelerometer to develop a functional compass app. By the time you’re done, you’ll be able to start playing around with sensors via the Android API.
Getting Started
In this tutorial, you’ll work on a sample app called Locaty. You’ll develop this app into a working compass. You’ll also enable reading and processing sensor data while the app is in the background via a persistent notification that will show you the angle and direction your device is facing.
Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.
Extract the ZIP file and open the starter project in Android Studio 4.0 or later by selecting Open an existing Android Studio project from the welcome screen.
Once the Gradle sync is complete, explore the project structure. The project has two files. Familiarize yourself with the files present — you’ll use them in this tutorial.
Build and run. You’ll see a simple screen with a compass image at the center as below:
Before you jump into writing any more code, there are some important things you should learn about sensors first. Time to jump over to the next section :]
Types of Sensors
The Android platform supports three broad categories of sensors:
Motion Sensors
These sensors track movement; they include accelerometers, gyroscopes and gravity sensors. They provide data on forces like acceleration and rotation that act on the sensor’s three-dimensional axes.
Environmental Sensors
Barometers and thermometers are types of sensors that access environmental metrics. These sensors monitor environmental variables like air pressure and temperature.
Position Sensors
Magnetometer and orientation sensors help determine the physical position of a device.
Each of these categories represents many specific sensors that are available on a device. You will go through them next.
List of Sensors
Android SDK provides you with a list of various types of sensors that you can use in your app. The availability of these sensors may vary from device to device.
Here’s a quick rundown of each sensor:
-
TYPE_ACCELEROMETER
Type: Hardware
Computes the acceleration in m/s2 applied on all three axes (x, y and z), including the force of gravity. -
TYPE_AMBIENT_TEMPERATURE
Type: Hardware
Monitors the temperature of the surroundings in degrees Celsius. -
TYPE_GRAVITY
Type: Software or Hardware
Computes the gravitational force in m/s2 applied on all three axes (x, y and z). -
TYPE_GYROSCOPE
Type: Hardware
Computes the rate of rotation in rad/s around each of the three axes (x, y and z). -
TYPE_LIGHT
Type: Hardware
Evaluates the light around a surrounding in lx units. -
TYPE_LINEAR_ACCELERATION
Type: Software or Hardware
Computes the acceleration force in m/s2 applied on all three axes (x, y and z), excluding the force of gravity. -
TYPE_MAGNETIC_FIELD
Type: Hardware
Computes the geomagnetic field for all three axes in tesla (μT). -
TYPE_ORIENTATION
Type: Software
Computes the degree of rotation around all three axes. -
TYPE_PRESSURE
Type: Hardware
Computes the air pressure in hPa or mbar. -
TYPE_PROXIMITY
Type: Hardware
Computes the proximity of the device’s screen to an object in centimeters. -
TYPE_RELATIVE_HUMIDITY
Type: Hardware
Computes the humidity of the surrounding air as a percentage (%). -
TYPE_ROTATION_VECTOR
Type: Software or Hardware
Computes the orientation of a device by the device’s rotation vector. -
TYPE_TEMPERATURE
Type: Hardware
Monitors the temperature of the surroundings in degrees Celsius. In API 14, the TYPE_AMBIENT_TEMPERATURE sensor replaced this sensor.
Combining Sensor Data With Sensor Fusion
Typically, you can develop a compass just with a magnetometer. If you want more accurate data, however, you can combine a magnetometer with an accelerometer. This method of using data from two or more sensors to get a more accurate result is known as Sensor Fusion.
Now, it’s time to start putting to use all this information. You already have the starter app up and running. You are going to start adding implementation details in order to make the compass functional. Head over to the next section to begin.
Setting up Sensors
Open LocatyService.kt and create a variable to hold the reference to SensorManager
:
private lateinit var sensorManager: SensorManager
Android Studio now prompts you to import SensorManager
, so import android.hardware.SensorManager.
Next, in onCreate
, add the following code:
// 1
sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
// 2
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also { accelerometer ->
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI)
}
// 3
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also { magneticField ->
sensorManager.registerListener(this, magneticField, SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI)
}
After you add the code above, import android.hardware.Sensor.
Here’s a step-by-step explanation of what the code above does:
- Initializes
SensorManager
. - Registers a sensor event callback to listen to changes in the accelerometer.
- Registers a sensor event callback to listen to changes in the magnetometer.
Android SDK provides four constants, which inform the Android system how often to tap into the computed events:
-
SENSOR_DELAY_FASTEST
: Gets sensors data as soon as possible -
SENSOR_DELAY_GAME
: Gets sensors data at a rate suitable for games -
SENSOR_DELAY_UI
: Gets sensors data at a rate suitable for working with user interfaces -
SENSOR_DELAY_NORMAL
: Gets sensors data at a rate suitable for screen orientation changes
To listen to the event changes in the sensors, you need to implement the interface SensorEventListener
and override its methods onAccuracyChanged
and onSensorChanged
.
To do that, start by adding the following imports:
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
After that, implement SensorEventListener
in LocatyService
:
class LocatyService : Service(), SensorEventListener {
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onSensorChanged(event: SensorEvent?) {
}
}
Android system calls onSensorChanged
every time there’s a new sensor event. Its SensorEvent
parameter gives a set of array of size three, where each index represents a value of an axes in a coordinate system: event.values[0]
represents x, event.values[1]
represents y and event.values[2]
for z.
On the other hand, Android system only calls onAccuracyChanged
when there’s a change in accuracy. SensorManager
contains all the accuracy change constants in SensorManager.SENSOR_STATUS_*
.