How to add fixed delay in sensors readings in kotlin?

30 Views Asked by At

I'm making a data collection app in kotlin to collect phones sensors readings. I'm using background service to keep the service running in the background.

What i wanna do is that I want sensors values to be recorded after every 5 minutes. I want to add a 5 minute delay so that the sensors are not occupied all the time, they should be occupied only after every 5 minutes gap to record values. After recording values, sensors should be unoccupied. The problem I'm facing is I'm getting continuous values of sensors without any delay which results in high amount of data. I'm not getting a fixed delay. Below is my Service code.

package com.example.sensorsapp

import android.app.Service
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.sqlite.SQLiteDatabase
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Handler
import android.os.IBinder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

data class SensorData(val sensorType: String, val value: Float, val timestamp: String)

class SensorDataService : Service(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private lateinit var dbHelper: MyDatabaseHelper
    private lateinit var db: SQLiteDatabase
    private lateinit var handler: Handler
    private val recordedData = mutableMapOf<Int, Triple<Float, Float, Float>>()

    private lateinit var sensors: List<Sensor>

    override fun onCreate() {
        super.onCreate()

        // Initialize the sensor manager
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

        // Add the sensors you want to monitor
        sensors = listOf(
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
            sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY),
            sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
            sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
            sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),
            sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
        )

        // Initialize the database helper
        dbHelper = MyDatabaseHelper(this)
        db = dbHelper.writableDatabase

        // Initialize the handler for scheduling
        handler = Handler()

        // Start the delayed loop
        startDelayedLoop()
    }

    private fun startDelayedLoop() {
        handler.postDelayed(object : Runnable {
            override fun run() {
                // Perform sensor readings and record data
                sensors.forEach { sensor ->
                    val sensorData = getSensorData(sensor)
                    insertSensorData(sensorData)
                }

                // Schedule the next iteration after a 5-minute delay
                handler.postDelayed(this, 5 * 60 * 1000)

                // Stop the sensor readings after 5 minutes
                handler.postDelayed({
                    // Unregister the sensor listener and close the database
                    for (sensor in sensors) {
                        sensorManager.unregisterListener(this@SensorDataService, sensor)
                    }
                    db.close()
                }, 5 * 60 * 1000)
            }
        }, 0)
    }

    private fun getSensorData(sensor: Sensor): SensorData {
        // Replace with your actual logic to obtain sensor data
        val sensorType = sensor.getStringType()
        val value = 0.0f // Replace with your actual sensor value
        val timestamp = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
        return SensorData(sensorType, value, timestamp)
    }

    private fun insertSensorData(sensorData: SensorData) {
        // Insert data into the sensor_data table
        val values = ContentValues().apply {
            put(MyDatabaseHelper.TIMESTAMP, sensorData.timestamp)
            put(MyDatabaseHelper.SENSOR_NAME, sensorData.sensorType)
            put(MyDatabaseHelper.X_VALUE, sensorData.value)
            put(MyDatabaseHelper.Y_VALUE, 0.0) // Assuming you have X, Y, and Z values
            put(MyDatabaseHelper.Z_VALUE, 0.0)
        }
        db.insert(MyDatabaseHelper.TABLE_NAME, null, values)
    }

    // Implement your other sensor event handling methods here

    // ... (onAccuracyChanged, onSensorChanged)

    override fun onDestroy() {
        super.onDestroy()
        // Unregister the sensor listener and close the database when the service is destroyed
        for (sensor in sensors) {
            sensorManager.unregisterListener(this, sensor)
        }
        db.close()
    }

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

    override fun onSensorChanged(event: SensorEvent?) {
        // Your existing sensor event handling logic
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

0

There are 0 best solutions below