Skip to main content

Working with Sensors

1. Accessing Sensor Service

Property Description Example
SensorManager Class to access sensor data SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor.TYPE_ACCELEROMETER Constant for accelerometer sensor sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor.TYPE_GYROSCOPE Constant for gyroscope sensor sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
Sensor.TYPE_LIGHT Constant for light sensor sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
Sensor.TYPE_MAGNETIC_FIELD Constant for magnetic field sensor sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Sensor.TYPE_PROXIMITY Constant for proximity sensor sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
Sensor.TYPE_TEMPERATURE Constant for temperature sensor sensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);

Example: Registering a Sensor Listener

class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private lateinit var accelerometer: Sensor

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(sensorEventListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(sensorEventListener)
    }

    private val sensorEventListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent?) {
            event?.let {
                val x = it.values[0]
                val y = it.values[1]
                val z = it.values[2]
                // Process sensor data
            }
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
    }
}

2. Listing Available Sensors

Sensor Type Description Usage Notes
TYPE_ACCELEROMETER Measures acceleration force in m/s² along a device's X, Y, and Z axis. Used for motion detection, tilt sensing, and gesture recognition. NEW in Android 13
TYPE_GYROSCOPE Measures the rate of rotation in rad/s around a device's X, Y, and Z axis. Used for 3D orientation tracking and camera stabilization. NEW in Android 13
TYPE_LIGHT Measures the ambient light level in lux. Used for automatic screen brightness adjustment. Deprecated since Android 10
TYPE_MAGNETIC_FIELD Measures the ambient magnetic field in μT for X, Y, and Z axis. Used for compass functionality and navigation. NEW in Android 13
TYPE_PROXIMITY Measures the proximity of an object in cm to the device sensor. Used for screen off when phone is near ear during calls. NEW in Android 13
TYPE_TEMPERATURE Measures the ambient air temperature in Celsius. Used for environmental monitoring and health tracking. Deprecated since Android 10

Example: Listing Available Sensors

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensors = sensorManager.getSensorList(Sensor.TYPE_ALL)

for (sensor in sensors) {
    println("Sensor Name: ${sensor.name}")
    println("Sensor Type: ${sensor.type}")
    println("Vendor: ${sensor.vendor}")
    println("Version: ${sensor.version}")
}

3. Registering Sensor Listeners

Method Description Parameters Notes
registerListener() Registers a sensor listener to receive sensor events listener: SensorEventListener, sensor: Sensor, delay: Int Must be called on the main thread. Delay values are defined in SensorManager.
unregisterListener() Unregisters a sensor listener listener: SensorEventListener Must be called to prevent memory leaks and unnecessary battery drain.

Example: Registering a Sensor Listener

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

val sensorListener = object : SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        val x = event.values[0]
        val y = event.values[1]
        val z = event.values[2]
        // Process sensor data
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Handle accuracy changes
    }
}

sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
Note: Always unregister listeners in onPause() or onStop() to avoid memory leaks.

Key Points

  • Use SensorManager to access sensors.
  • Implement SensorEventListener to handle sensor data.
  • Register listeners with appropriate delay values for performance.

4. Unregistering Listeners

Unregistering listeners is crucial to prevent memory leaks and unnecessary resource consumption. Android provides methods to unregister sensor listeners.

Method Description Notes
SensorManager.unregisterListener() Unregisters a sensor listener Must be called to clean up resources

Example: Unregistering a Sensor Listener

class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private lateinit var accelerometer: Sensor
    private val sensorListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            // Handle sensor data
        }

        override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
            // Handle accuracy changes
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)!!
    }

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(sensorListener) // Unregister listener
    }
}
Note: Always unregister listeners in onPause() or onStop() to prevent memory leaks and ensure proper cleanup.

5. Handling Sensor Events

Event Type Description Parameters Notes
onSensorChanged Called when sensor data is updated SensorEvent Triggered by sensor hardware or system
onAccuracyChanged Called when sensor accuracy changes Sensor, accuracy Use to adjust sensor behavior based on accuracy level

Example: Registering Sensor Listener

class SensorActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private lateinit var accelerometer: Sensor

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }

    override fun onSensorChanged(event: SensorEvent) {
        val x = event.values[0]
        val y = event.values[1]
        val z = event.values[2]
        // Process sensor data
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Handle accuracy changes
    }
}
Note: Always unregister listeners in onPause to prevent memory leaks and unnecessary battery drain.

Sensor Event Handling Workflow

  • Implement SensorEventListener interface
  • Get SensorManager instance
  • Register listener with desired sensor and delay
  • Override onSensorChanged to process new data
  • Override onAccuracyChanged to handle accuracy updates
  • Unregister listener in onPause

6. Using Accelerometer

Property Description Values
sensorType Defines the type of sensor SENSOR_TYPE_ACCELEROMETER
resolution Minimum change in acceleration that triggers a sensor event 0.01 m/s²
powerConsumption Estimated power consumption in mA 0.15 mA

Example: Reading Accelerometer Data

class AccelerometerActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onSensorChanged(event: SensorEvent) {
        val x = event.values[0]
        val y = event.values[1]
        val z = event.values[2]

        Log.d("Accelerometer", "X: $x, Y: $y, Z: $z")
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}
Note: Ensure that the app has android.permission.ACCESS_FINE_LOCATION if location-based sensor data is required.
Warning: Accelerometer readings can be affected by device orientation and external forces. Always validate sensor data in your application logic.

7. Working with Gyroscope

Property Description Notes
Sensor.TYPE_GYROSCOPE Identifies the gyroscope sensor Available on most modern Android devices
Sensor.TYPE_GYROSCOPE_UNCALIBRATED Provides uncalibrated gyroscope data Includes bias values for calibration

Example: Reading Gyroscope Data

class GyroscopeActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var gyroscopeSensor: Sensor? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        gyroscopeSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
    }

    override fun onSensorChanged(event: SensorEvent) {
        val x = event.values[0]
        val y = event.values[1]
        val z = event.values[2]

        // Process gyroscope data
        Log.d("Gyroscope", "X: $x, Y: $y, Z: $z")
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}

Example: Registering Sensor Listener

class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var gyroscopeSensor: Sensor? = null

    override fun onResume() {
        super.onResume()
        gyroscopeSensor?.let {
            sensorManager.registerListener(sensorEventListener, it, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(sensorEventListener)
    }

    private val sensorEventListener = object : SensorEventListener {
        override fun onSensorChanged(event: SensorEvent) {
            if (event.sensor.type == Sensor.TYPE_GYROSCOPE) {
                val rotationVector = event.values
                // Use rotation vector for orientation calculations
            }
        }

        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
    }
}
Note: Gyroscope data is in radians per second. For accurate orientation calculations, consider using RotationVector or Quaternion methods.
Warning: Not all devices have a gyroscope sensor. Always check for sensor availability before registering listeners.

8. Using Proximity Sensor

Property Description Values
Sensor.TYPE_PROXIMITY Proximity sensor type identifier 8
sensorManager Instance of SensorManager to access sensors SensorManager
proximitySensor Proximity sensor object Sensor

Example: Registering Proximity Sensor

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)

val sensorEventListener = object : SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        val distance = event.values[0]
        if (distance == 0f) {
            // Object is close to sensor
            println("Object detected near proximity sensor")
        } else {
            // Object is far from sensor
            println("Object not detected near proximity sensor")
        }
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

sensorManager.registerListener(sensorEventListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL)
Note: The proximity sensor typically returns a value of 0.0f when an object is close to the sensor and a higher value when it's farther away. The exact distance depends on the device.

9. Working with Light Sensor

Property Description Values
sensor.type Light sensor type TYPE_LIGHT
sensor.resolution Resolution in lux 0.1
sensor.power Power consumption in mA 0.15

Example: Reading Light Sensor Data

import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager

class LightSensorActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var lightSensor: Sensor? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_light_sensor)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
    }

    override fun onSensorChanged(event: SensorEvent?) {
        if (event?.sensor?.type == Sensor.TYPE_LIGHT) {
            val lightValue = event.values[0]
            // Process light value (lux)
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        // Handle sensor accuracy changes
    }

    override fun onResume() {
        super.onResume()
        lightSensor?.let { sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_NORMAL) }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}
Note: Light sensor values are reported in lux units. The sensor provides a single value representing ambient light intensity.

10. Monitoring Device Orientation

Property Description Values
orientation Current device orientation ORIENTATION_UNKNOWN, ORIENTATION Portrait, ORIENTATION_LANDSCAPE
rotation Rotation of the device in degrees 0, 90, 180, 270

Example: Detecting Orientation Changes

import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager

class OrientationSensorActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var orientationSensor: Sensor? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION)
    }

    override fun onSensorChanged(event: SensorEvent?) {
        if (event?.sensor?.type == Sensor.TYPE_ORIENTATION) {
            val orientation = event.values[0]
            when (orientation.toInt()) {
                0 -> {
                    // Portrait
                }
                90 -> {
                    // Landscape (right)
                }
                180 -> {
                    // Portrait (upside down)
                }
                270 -> {
                    // Landscape (left)
                }
            }
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}

    override fun onResume() {
        super.onResume()
        sensorManager.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL)
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}
Note: The TYPE_ORIENTATION sensor is deprecated as of Android API level 30. Use TYPE_GAME_ROTATION_VECTOR or TYPE_ROTATION_VECTOR for better accuracy.
Warning: Orientation sensor data can be inaccurate on devices with low-quality sensors or when the device is in a non-standard position.

Was this article helpful?