안드로이드 세계

[Android] WorkManager 특정시간알림 본문

안드로이드(Android)/코틀린(Kotlin)

[Android] WorkManager 특정시간알림

리안94 2021. 6. 1. 14:24

AlarmManager처럼 특정시간을 세팅해준다면 아주편하게 사용할 수 있겠지만, WorkManager는 불가능하다.

 

따라서 딜레이주는 방식으로 세팅을해주어야하는데, 특정시간을 지정해주는 알고리즘은 다음과같다.

 

fun getCertainTime(): Long{

    val currentDate = Calendar.getInstance()
    val dueDate = Calendar.getInstance().apply {

        set(Calendar.HOUR_OF_DAY, 2)
        set(Calendar.MINUTE, 20)
        set(Calendar.SECOND, 0)

    }

    if (dueDate.before(currentDate))
        dueDate.add(Calendar.HOUR_OF_DAY, 24)

    return dueDate.timeInMillis - currentDate.timeInMillis
}

 

워크매니저에는 다음과 같이 세팅해준다.

 

class WorkApplication : Application() {

    private val backgroundCoroutineScope = CoroutineScope(Dispatchers.Default)

    override fun onCreate() {
        super.onCreate()
        delayCreateWork()
    }

    private fun delayCreateWork(){
        backgroundCoroutineScope.launch {
            createWorkManager()
        }
    }

    private fun createWorkManager(){
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)
            .setRequiresBatteryNotLow(true)
            .setRequiresCharging(true)
            .setRequiresStorageNotLow(true)
            .build()

        val oneTimeWorkRequest = OneTimeWorkRequestBuilder<Worker>().
            setInitialDelay(getCertainTime(), TimeUnit.MILLISECONDS).
            setConstraints(constraints).build()

        WorkManager.getInstance(applicationContext).enqueueUniqueWork(Worker.WORK_NAME, ExistingWorkPolicy.KEEP, oneTimeWorkRequest)
    }
}

이렇게만 세팅해주면 일회성세팅이기때문에 워커에도 다음과같이 구성한다.

 

class Worker(appContext: Context, parameters: WorkerParameters) : CoroutineWorker(appContext, parameters) {

    companion object{
        const val WORK_NAME = "Notification Work"
    }

    override suspend fun doWork(): Result {

        try { 
            //Work
            
            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.UNMETERED)
                .setRequiresBatteryNotLow(true)
                .setRequiresCharging(true)
                .setRequiresStorageNotLow(true)
                .build()

            val oneTimeWorkRequest = OneTimeWorkRequestBuilder<Worker>().
                setInitialDelay(getCertainTime(), TimeUnit.MILLISECONDS).
                setConstraints(constraints).build()

            WorkManager.getInstance(applicationContext).enqueueUniqueWork(Worker.WORK_NAME, ExistingWorkPolicy.REPLACE, oneTimeWorkRequest)

        }catch (e: Exception){
            Result.retry()
        }

        return Result.success()
    }

}

 

어떠한 워커작업이 끝나면 다시세팅해준다.

 

워커에서는 REPLACE로 작업을 세팅해주어야하는데, 그이유는 워커에 등록된 이전 작업이 완전히종료가된상태가 아니기때문이다.

 

1분마다 세팅한 결과

 

 

아래의 깃은 간단하게 로그찍어보는 샘플이다.

https://github.com/pyg1007/WorkManager-Sample

 

pyg1007/WorkManager-Sample

Contribute to pyg1007/WorkManager-Sample development by creating an account on GitHub.

github.com

 

Comments