Skip to content

Instantly share code, notes, and snippets.

@wertgit
Created November 27, 2019 06:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wertgit/1aff1827de1406d69c49e0db2eb35b95 to your computer and use it in GitHub Desktop.
Save wertgit/1aff1827de1406d69c49e0db2eb35b95 to your computer and use it in GitHub Desktop.
ReminderWorker
import android.R
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import androidx.core.app.NotificationCompat
import androidx.work.*
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.threeten.bp.Duration
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalTime
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.temporal.ChronoUnit
import timber.log.Timber
import java.util.concurrent.TimeUnit
import java.util.*
/**
* Worker class that defines what needs to be executed.
* Work to be done is handled in the doWork() function.
* We extend KoinComponent so we can inject objects because DI why ( Get is the Joke)
*/
class ReminderWorker(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {
@SuppressLint("CheckResult")
override fun doWork(): Result {
sendNotification("Timesheet Reminder", "Don't forget to fill up your timesheet.")
runAt() // schedule the work for next day
// repository.getExternalIPAddress().subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe({ response ->
// Timber.d("Public IP : ${response.ipAddress}")
// }, { error ->
// Timber.d("Error in $TAG ${error.message}")
// })
// Indicate whether the task finished successfully with the Result
return Result.success()
}
fun addHoursToJavaUtilDate(date: Date, hours: Int): Date {
val calendar = Calendar.getInstance()
calendar.setTime(date)
calendar.add(Calendar.HOUR_OF_DAY, hours)
return calendar.getTime()
}
companion object : KoinComponent {
private val repository: ClockInRepository by inject()
private const val REMINDER_NAME = "TIMESHEETREMINDER"
fun runAt() {
val isClockedIn = repository.isClockedIn
val workManager = WorkManager.getInstance()
val formatter = DateTimeFormatter.ofPattern(CLOCKEDIN_DATETIME_FORMAT)
// Operate only if the user clocked in else cancel notification
// Check the user clockin time and add 8hr 30min or total worktime
// Set up next day scedhule
if(isClockedIn){
val clockInTime = repository.clockedInTime
var clockInLocalDateTime = LocalDateTime.parse(clockInTime, formatter)
Timber.d("clockInTime? : $clockInTime")
Timber.d("clockInLocalDateTime? : $clockInLocalDateTime")
// We add time based on the total working hours.
clockInLocalDateTime = addTimeToLocalTime(clockInLocalDateTime,8,30)
Timber.d("timeAfterAddition? : $clockInLocalDateTime")
Timber.d("Hour? : ${clockInLocalDateTime.hour}")
Timber.d("Min? : ${ clockInLocalDateTime.minute}")
// val duration = durationBasedOnTriggerTime(15,4)
val duration = durationBasedOnTriggerTime(clockInLocalDateTime.hour,clockInLocalDateTime.minute)
Timber.d("runAt=${duration.seconds}s")
// optional constraints
/*
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
*/
/**
* To execute a worker at the same time daily, OneTimeWorkRequest is preffered
* over Periodic
*/
val workRequest = OneTimeWorkRequest.Builder(TimesheetAddReminderWorker::class.java)
.setInitialDelay(30, TimeUnit.SECONDS)
// .setInitialDelay(duration.seconds, TimeUnit.SECONDS)
.build()
/**
* To avoid accidentally setting up multiple alarm/request we use enqueueUniqueWork
*
*/
workManager.enqueueUniqueWork(REMINDER_NAME, ExistingWorkPolicy.REPLACE, workRequest)
}
}
fun cancel() {
// Timber.d("cancel")
val workManager = WorkManager.getInstance()
workManager.cancelUniqueWork(REMINDER_NAME)
}
fun durationBasedOnTriggerTime(hour:Int,minute:Int): Duration{
// trigger at 8:30am
val alarmTime = LocalTime.of(hour, minute)
var now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)
val nowTime = now.toLocalTime()
// if same time, schedule for next day as well
// if today's time had passed, schedule for next day
if (nowTime == alarmTime || nowTime.isAfter(alarmTime)) {
now = now.plusDays(1)
}
now = now.withHour(alarmTime.hour)
.withMinute(alarmTime.minute) // .withSecond(alarmTime.second).withNano(alarmTime.nano)
val duration = Duration.between(LocalDateTime.now(), now)
return duration
}
fun addTimeToLocalTime(localDateTime: LocalDateTime,hours:Long,minutes:Long):LocalDateTime{
return localDateTime.plusHours(hours).plusMinutes(minutes)
}
}
fun sendNotification(title: String, message: String) {
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//If on Oreo then notification required a notification channel.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val channel =
NotificationChannel("default", "Default", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(applicationContext, "default")
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.sym_def_app_icon)
notificationManager.notify(1, notification.build())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment