How to Obtain the Accelerometer Data in Android Using Kotlin 2024

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 a SensorEvent 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 a Sensor 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: A Sensor 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 are SensorManager.SENSOR_STATUS_ACCURACY_HIGH, SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM, SensorManager.SENSOR_STATUS_ACCURACY_LOW, or SensorManager.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: A SensorEventListener object that will receive the sensor data.
  • sensor: A Sensor 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 are SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI, SensorManager.SENSOR_DELAY_GAME, or SensorManager.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: A SensorEventListener 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.

Related post