Created
December 5, 2022 08:27
-
-
Save shubhamvashisht/4fbe420220cf1e0984ebbff2e58987f4 to your computer and use it in GitHub Desktop.
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
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