Created
November 27, 2019 06:53
-
-
Save wertgit/1aff1827de1406d69c49e0db2eb35b95 to your computer and use it in GitHub Desktop.
ReminderWorker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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