0

I'm a newbie with Kotlin. I'm getting Sensor data using the WorkManager. Since the task is somehow being killed before collecting a certain amount of data points, I'm creating another task before calling the Result.success() method to carry on the work even if the task is killed.

Foreground Worker Class:

class ForegroundWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
    setForeground(createForegroundInfo())
    return@withContext runCatching {
        initializeLocalVariables()
        startWorking()
        val pm: PowerManager = mContext.getSystemService(Context.POWER_SERVICE) as PowerManager
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock")
        //If the WakeLock is released, Acquire it again
        if (mWakeLock != null && !mWakeLock!!.isHeld)
            mWakeLock!!.acquire()
        WorkManager.getInstance(mContext)
        .beginUniqueWork(TAG, ExistingWorkPolicy.APPEND_OR_REPLACE,
        OneTimeWorkRequest.from(ForegroundWorker::class.java)).enqueue()
        Result.success()
    }.getOrElse {
        Result.failure()
    }
}

private suspend fun startWorking() {
    if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        try
        {
            // Subscribe to location changes
            mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,mLocationCallback,Looper.getMainLooper())
        }
        catch (unlikely: SecurityException)
        {
            Log.d(TAG, "Lost location permissions. Couldn't remove updates.")
        }

        //Check if the Accelerometer is available in this device
        if (mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER) && mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
            //Register the Accelerometer
            mSensorManager!!.registerListener(mSensorEventListener, mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI,mSensorHandler)
        }

        //Check if the Gyroscope is available in this device
        if (mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_GYROSCOPE) && mSensorManager!!.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null) {
            //Register the Gyroscope
            mSensorManager!!.registerListener(mSensorEventListener,mSensorManager!!.getDefaultSensor(Sensor.TYPE_GYROSCOPE),SensorManager.SENSOR_DELAY_UI,mSensorHandler)
        }
        startMonitoring()
    }
    else
    {
        Toast.makeText(mContext,"Location permissions are NOT granted.",Toast.LENGTH_SHORT).show()
    }

    while (mIsDataSent < 12)
    {
        //Do Nothing !
        //Wait for the Task to send 12 chunks of data to Server
    }
}

private fun startMonitoring() {
    //Check if the Accelerometer is available in this device
    if (mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER) && mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
        //Register the Accelerometer
        mSensorManager!!.registerListener(mSensorEventListener, mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI,mSensorHandler)
    }
    //Check if the Gyroscope is available in this device
    if (mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_GYROSCOPE) && mSensorManager!!.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null) {
        //Register the Gyroscope
        mSensorManager!!.registerListener(mSensorEventListener,mSensorManager!!.getDefaultSensor(Sensor.TYPE_GYROSCOPE),SensorManager.SENSOR_DELAY_UI,mSensorHandler)
    }
    // Subscribe to location changes.
    if (ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        if(mFusedLocationProviderClient != null)
        {
            mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,mLocationCallback,Looper.getMainLooper())
        }
    }
}
}

I'm starting the task from the main application using the following chunk of code:

 WorkManager.getInstance(this)
 .beginUniqueWork("ForegroundWorker", ExistingWorkPolicy.REPLACE,
 OneTimeWorkRequest.from(ForegroundWorker::class.java)).enqueue()

The problem here is that I need to kill/finish the task immediately when the User logs out from the application. I've read many questions including this. I've tried the cancellation methods but they are not working since the task is in Running state when I need to kill it. I was hoping to get a pid and then send the SIGKILL but I couldn't get any pid as well. Someone please guide me about the way to kill the task when it's in Running state.

Itban Saeed
  • 1,660
  • 5
  • 24
  • 35

0 Answers0