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
}
}