How to Obtain the Accelerometer Data in Android Using Kotlin 2024
The accelerometer is a sensor that measures the acceleration of the device along the three axes: x, y, and z. The acceleration is the change in velocity over time, and it includes the effect of gravity. For example, when the device is at rest on a flat surface, the accelerometer will measure a constant acceleration of about 9.8 m/s2 along the z-axis, which is the gravity. When the device is tilted or moved, the accelerometer will measure different values along the three axes, depending on the direction and magnitude of the acceleration.
In this post, I will show you how to obtain the accelerometer data in android using kotlin, a modern and concise programming language for android development.
What is SensorManager and Sensor?
To access the accelerometer data, we need to use the SensorManager
and Sensor
classes, which are part of the android.hardware package. The SensorManager
class provides access to the device’s sensors, such as the accelerometer, gyroscope, light, etc. The Sensor
class represents a specific sensor, such as the accelerometer, and contains information such as the name, type, range, resolution, etc.
To get an instance of the SensorManager
class, we need to use the getSystemService
method of the Context
class, which is the base class for all android components, such as activities, services, etc. The getSystemService
method takes a string constant as a parameter, which specifies the type of system service we want to access. In this case, we use the SENSOR_SERVICE
constant, which represents the sensor service. We also need to cast the return value of the getSystemService
method to the SensorManager
type, as the method returns a generic Object
type.
To get an instance of the Sensor
class, we need to use the getDefaultSensor
method of the SensorManager
class, which takes an integer constant as a parameter, which specifies the type of sensor we want to access. In this case, we use the Sensor.TYPE_ACCELEROMETER
constant, which represents the accelerometer sensor. The getDefaultSensor
method returns a Sensor
object, or null if the device does not have the requested sensor.
Here is an example of how to get the SensorManager
and Sensor
instances using kotlin:
private lateinit var sensorManager: SensorManager // a variable to store the sensor manager
private var sensor: Sensor? = null // a variable to store the sensor
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager // get the sensor manager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) // get the sensor
}
In this example, we declare two variables to store the SensorManager
and Sensor
instances, using the lateinit
and var
keywords, respectively. The lateinit
keyword indicates that the variable will be initialized later, and the var
keyword indicates that the variable can be reassigned. We initialize the variables in the onCreate
method of the activity, which is called when the activity is created. We use the setContentView
method to set the layout of the activity, using the binding
object, which is generated by the view binding feature of android studio.
What is SensorEventListener and SensorEvent?
To obtain the accelerometer data, we need to implement the SensorEventListener
interface, which defines two methods that are called when the sensor data changes or the sensor accuracy changes. The SensorEventListener
interface is also part of the android.hardware package. The two methods are:
onSensorChanged
: This method is called when the sensor data changes. It takes aSensorEvent
object as a parameter, which contains the sensor data, such as the values, timestamp, accuracy, etc.onAccuracyChanged
: This method is called when the sensor accuracy changes. It takes aSensor
object and an integer constant as parameters, which represent the sensor and the new accuracy, respectively.
The SensorEvent
class is also part of the android.hardware package, and it represents a single sensor event. The SensorEvent
class contains the following fields:
sensor
: ASensor
object that represents the sensor that generated the event.values
: A float array that contains the sensor data. For the accelerometer sensor, the array has three elements, which represent the acceleration along the x, y, and z axes, in m/s2.timestamp
: A long value that represents the time in nanoseconds when the event occurred.accuracy
: An integer constant that represents the accuracy of the sensor data. The possible values areSensorManager.SENSOR_STATUS_ACCURACY_HIGH
,SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM
,SensorManager.SENSOR_STATUS_ACCURACY_LOW
, orSensorManager.SENSOR_STATUS_UNRELIABLE
.
To implement the SensorEventListener
interface, we can use an anonymous object expression in kotlin, which creates an object of an unnamed class that implements the interface. We can override the two methods of the interface and provide our own logic to handle the sensor data and accuracy changes. Here is an example of how to create a SensorEventListener
object using kotlin:
private lateinit var sensorEventListener: SensorEventListener // a variable to store the sensor event listener
sensorEventListener = object : SensorEventListener { // create an anonymous object that implements the interface
override fun onSensorChanged(event: SensorEvent?) { // override the onSensorChanged method
val x = event!!.values[0] // get the x-axis acceleration
val y = event.values[1] // get the y-axis acceleration
val z = event.values[2] // get the z-axis acceleration
// do something with the accelerometer data
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { // override the onAccuracyChanged method
// do something with the sensor accuracy
}
}
In this example, we declare a variable to store the SensorEventListener
object, using the lateinit
keyword. We initialize the variable by creating an anonymous object that implements the SensorEventListener
interface, using the object
keyword. We override the two methods of the interface, using the override
keyword. We use the event
parameter of the onSensorChanged
method to get the accelerometer data, using the values
field. We use the !!
operator to assert that the event
object is not null, as the method can be called with a null parameter in some cases. We use the sensor
and accuracy
parameters of the onAccuracyChanged
method to get the sensor and the new accuracy, respectively.
How to Register and Unregister the SensorEventListener?
To receive the sensor data, we need to register the SensorEventListener
object with the SensorManager
object, using the registerListener
method. The registerListener
method takes four parameters:
listener
: ASensorEventListener
object that will receive the sensor data.sensor
: ASensor
object that represents the sensor to be monitored.samplingPeriodUs
: An integer value that specifies the rate at which the sensor data will be delivered, in microseconds. The possible values areSensorManager.SENSOR_DELAY_NORMAL
,SensorManager.SENSOR_DELAY_UI
,SensorManager.SENSOR_DELAY_GAME
, orSensorManager.SENSOR_DELAY_FASTEST
.maxReportLatencyUs
: An integer value that specifies the maximum time in microseconds that the sensor data can be delayed before being delivered, for power saving purposes. This parameter is optional and can be omitted.
To stop receiving the sensor data, we need to unregister the SensorEventListener
object from the SensorManager
object, using the unregisterListener
method. The unregisterListener
method takes one parameter:
listener
: ASensorEventListener
object that will no longer receive the sensor data.
Here is an example of how to register and unregister the SensorEventListener
object using kotlin:
sensorManager.registerListener( // register the listener
sensorEventListener, // the listener object
sensor, // the sensor object
SensorManager.SENSOR_DELAY_NORMAL // the sampling period
) // omit the max report latency parameter
sensorManager.unregisterListener(sensorEventListener) // unregister the listener
In this example, we use the sensorManager
and sensorEventListener
variables that we declared and initialized earlier. We use the sensor
variable to specify the accelerometer sensor. We use the SensorManager.SENSOR_DELAY_NORMAL
constant to specify the normal sampling rate, which is suitable for screen orientation changes. We omit the maxReportLatencyUs
parameter, as we do not need to save power in this case. We register the listener in the onCreate
method of the activity, and we unregister the listener in the onDestroy
method of the activity, which are called when the activity is created and destroyed, respectively.