Skip to content

Instantly share code, notes, and snippets.

@shubhamvashisht
Created December 5, 2022 08:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shubhamvashisht/4fbe420220cf1e0984ebbff2e58987f4 to your computer and use it in GitHub Desktop.
Save shubhamvashisht/4fbe420220cf1e0984ebbff2e58987f4 to your computer and use it in GitHub Desktop.
package com.radio.pocketfm.app.helpers
import android.content.Context
import android.os.Bundle
import androidx.work.*
import com.radio.pocketfm.app.RadioLyApplication
import com.radio.pocketfm.app.mobile.notifications.NotificationHandler
import com.radio.pocketfm.app.mobile.notifications.NotificationKeys
import com.radio.pocketfm.app.shared.CommonLib
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
import java.util.concurrent.TimeUnit
class LocalNotificationHandler {
companion object {
const val SCHEDULED_NOTI_TAG = "scheduled_noti_tag"
const val DEFERRED_NOTI_TAG = "deferred_noti_tag"
const val LOCAL_NOTI_TAG = "local_notification"
const val IS_LOCAL_NOTIFICATION = "is_local_notification"
fun schedule() {
val workManager = WorkManager.getInstance(RadioLyApplication.instance)
scheduleRegularNotification(workManager)
scheduleDeferredNotification(workManager, false)
}
fun scheduleRegularNotification(workManager: WorkManager) {
val scheduledNotificationWorkRequest = OneTimeWorkRequest.Builder(ScheduledNotificationWorker::class.java)
.setInitialDelay(24, TimeUnit.HOURS)
.build()
workManager.enqueueUniqueWork(SCHEDULED_NOTI_TAG, ExistingWorkPolicy.REPLACE, scheduledNotificationWorkRequest)
}
fun scheduleDeferredNotification(workManager: WorkManager, isDayRepeatInterval: Boolean) {
val rightNow: Calendar = Calendar.getInstance()
val currentHourIn24Format: Int = rightNow.get(Calendar.HOUR_OF_DAY)
val currentMin: Int = rightNow.get(Calendar.MINUTE)
val deferredNotificationHour: Int = when (currentHourIn24Format) {
in 21..23 -> {
var hasCrossedIgnoreThreshold = false
if (currentHourIn24Format > 21) {
hasCrossedIgnoreThreshold = true
}
else {
if (currentMin >= 30) {
hasCrossedIgnoreThreshold = true
}
}
if (hasCrossedIgnoreThreshold) {
currentHourIn24Format - 3
}
else {
3
}
}
in 0..3 -> {
//special case for time between 3:30AM - 3:59 AM
//here both +3/-3 windows falls between ignore period
//of 12:30 AM - 7AM, so we pick the same day +3 + minutes needed till 7AM
var hasStuckInBothWindows = false
if (currentHourIn24Format == 3) {
if (currentMin in 30..59) {
hasStuckInBothWindows = true
}
}
if (hasStuckInBothWindows) {
4
}
else {
24 - currentHourIn24Format
}
}
else -> {
3
}
}
val deferredNotificationWorkRequest = OneTimeWorkRequest.Builder(DeferredNotificationWorker::class.java)
.setInitialDelay(if (isDayRepeatInterval) 24L else deferredNotificationHour.toLong(), TimeUnit.HOURS)
.build()
workManager.enqueueUniqueWork(DEFERRED_NOTI_TAG, ExistingWorkPolicy.REPLACE, deferredNotificationWorkRequest)
}
/**
* Schedule a notification on a given time
*/
fun scheduleDeferredNotification(workManager: WorkManager, timeInMills: Long) {
val currentMillis = timeInMills - System.currentTimeMillis()
if (currentMillis > 0) {
CommonLib.setNotificationScheduled(true)
val deferredNotificationWorkRequest =
OneTimeWorkRequest.Builder(DeferredNotificationWorker::class.java)
.addTag(LOCAL_NOTI_TAG)
.setInputData(Data.Builder().put(IS_LOCAL_NOTIFICATION, true).build())
.setInitialDelay(currentMillis, TimeUnit.MILLISECONDS)
.build()
workManager.enqueueUniqueWork(
LOCAL_NOTI_TAG,
ExistingWorkPolicy.REPLACE,
deferredNotificationWorkRequest
)
}
}
fun cancelNotification() {
val workManager = WorkManager.getInstance(RadioLyApplication.instance)
workManager.cancelAllWorkByTag(SCHEDULED_NOTI_TAG)
workManager.cancelAllWorkByTag(DEFERRED_NOTI_TAG)
}
fun cancelLocalNotifications() {
WorkManager.getInstance(RadioLyApplication.instance).cancelAllWorkByTag(LOCAL_NOTI_TAG)
CommonLib.setNotificationScheduled(false)
}
}
}
class ScheduledNotificationWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
CoroutineScope(Dispatchers.Main).launch {
RadioLyApplication.instance.userUseCase.recentHistory.observeForever {
if (it != null && it.size > 0) {
val notificationId = "keep_listening${CommonLib.getFormattedDate(System.currentTimeMillis(), "yyyyMMdd")}"
val recentStory = it.first()
RadioLyApplication.instance.userUseCase.getShowDetail(recentStory.showId, false, false, "min").observeForever {
val bundle = Bundle()
bundle.putString(NotificationKeys.TYPE, "1")
bundle.putString(NotificationKeys.TITLE, "Today's New Episodes Unlocked")
bundle.putString(NotificationKeys.MESSAGE, "Click to Continue Listening to ${if (it != null) it.title else recentStory.title}")
bundle.putString(NotificationKeys.BIG_IMAGE, recentStory.imageUrl)
bundle.putString(NotificationKeys.ENTITY_ID, recentStory.storyId)
bundle.putString(NotificationKeys.ENTITY_TYPE, "story")
bundle.putString(NotificationKeys.NOTIFICATION_SERVER_ID, notificationId)
bundle.putString(NotificationKeys.NOTIFICATION_ACTION, "")
CoroutineScope(Dispatchers.IO).launch {
NotificationHandler().handleMessage(bundle, RadioLyApplication.instance, "local_notification")
}
CommonLib.setLocalNotificationData(recentStory.showId)
}
}
}
}
LocalNotificationHandler.scheduleRegularNotification(WorkManager.getInstance(RadioLyApplication.instance))
return Result.Success()
}
}
class DeferredNotificationWorker(val context: Context, val workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
val isLocalNotification = workerParams.inputData.getBoolean(LocalNotificationHandler.IS_LOCAL_NOTIFICATION, false)
CoroutineScope(Dispatchers.Main).launch {
RadioLyApplication.instance.userUseCase.recentHistory.observeForever {
if (it != null && it.size > 0) {
val notificationId = "keep_listening${CommonLib.getFormattedDate(System.currentTimeMillis(), "yyyyMMdd")}"
val recentStory = it.first()
RadioLyApplication.instance.userUseCase.getShowDetail(recentStory.showId, false, false, "min").observeForever {
val bundle = Bundle()
bundle.putString(NotificationKeys.TYPE, "1")
bundle.putString(NotificationKeys.TITLE, "Today's New Episodes Unlocked")
bundle.putString(NotificationKeys.MESSAGE, "Click to Continue Listening to ${if (it != null) it.title else recentStory.title}")
bundle.putString(NotificationKeys.BIG_IMAGE, recentStory.imageUrl)
bundle.putString(NotificationKeys.ENTITY_ID, recentStory.storyId)
bundle.putString(NotificationKeys.ENTITY_TYPE, "story")
bundle.putString(NotificationKeys.NOTIFICATION_SERVER_ID, notificationId)
bundle.putString(NotificationKeys.NOTIFICATION_ACTION, "")
if (isLocalNotification) {
bundle.putBoolean(NotificationKeys.IS_LOCAL, true)
}
CoroutineScope(Dispatchers.IO).launch {
NotificationHandler().handleMessage(
bundle,
RadioLyApplication.instance,
if (isLocalNotification) "local_personalised" else "local_notification"
)
}
CommonLib.setLocalNotificationData(recentStory.showId)
}
}
}
}
if (isLocalNotification) {
CommonLib.setNotificationScheduled(false)
} else {
LocalNotificationHandler.scheduleDeferredNotification(WorkManager.getInstance(RadioLyApplication.instance), true)
}
return Result.Success()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment