Skip to content

Commit

Permalink
Implemented Timezone Change broadcast receiver & Calibrated notificat…
Browse files Browse the repository at this point in the history
…ion.
  • Loading branch information
prateek-web2native authored and prateek-singh-3212 committed Aug 14, 2022
1 parent 77d7f97 commit b4d37d9
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
6 changes: 6 additions & 0 deletions AnkiDroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,12 @@
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".receiver.TimeZoneChangeReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>

<!-- stuff for Samsung Multi-Window -->
<uses-library
Expand Down
4 changes: 4 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.ichi2.anki.contextmenu.AnkiCardContextMenu;
import com.ichi2.anki.contextmenu.CardBrowserContextMenu;
import com.ichi2.anki.exception.StorageAccessException;
import com.ichi2.anki.receiver.TimeZoneChangeReceiver;
import com.ichi2.anki.services.BootService;
import com.ichi2.anki.services.NotificationService;
import com.ichi2.compat.CompatHelper;
Expand Down Expand Up @@ -251,6 +252,9 @@ public void onCreate() {
Timber.i("AnkiDroidApp: Starting Services");
new BootService().onReceive(this, new Intent(this, BootService.class));

Timber.i("AnkiDroidApp: Registering Broadcast Receivers");
TimeZoneChangeReceiver.Companion.registerTimeZoneChangeReceiver(this, new TimeZoneChangeReceiver());

// TODO: Notification CleanUP. Delete the Notification Service after successful implementation of Notification Work Manager.
// Register for notifications
mNotifications.observeForever(unused -> NotificationService.triggerNotificationFor(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2022 Prateek Singh <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.ichi2.anki.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.ichi2.anki.NotificationDatastore
import com.ichi2.anki.NotificationHelper
import com.ichi2.libanki.utils.TimeManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.*

/**
* Broadcast receiver to listen timezone change of user.
* Changes the notification triggering time when user timezone changes.
* */
class TimeZoneChangeReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
Timber.d("TimeZoneChangeReceiver Started...")

CoroutineScope(Dispatchers.Default).launch {
val notificationDatastore = NotificationDatastore.getInstance(context)

val oldTimezone: String = notificationDatastore.getString(TIMEZONE_KEY, "null")
val newTimezone: String = TimeZone.getDefault().id
val now = TimeManager.time.intTimeMS()

/**
* Get the current offset according to given TimeZone.
* */
fun getOffsetFromNow(timezone: String) = TimeZone.getTimeZone(timezone).getOffset(now)

if (oldTimezone != "null" || getOffsetFromNow(oldTimezone) == getOffsetFromNow(newTimezone)) {
Timber.d("No Timezone changed found...")
return@launch
}

Timber.d("Timezone changed...")
// Change the timezone to new timezone and recalculate the notification according to new time zone.
notificationDatastore.putStringAsync(TIMEZONE_KEY, newTimezone)

val oldCurrTimeMS = getZonedCurrTimeMS(oldTimezone)
val newCurrTimeMS = getZonedCurrTimeMS(newTimezone)
val timeDiffMS = oldCurrTimeMS - newCurrTimeMS

// Calibrate notification time.
NotificationHelper(context).calibrateNotificationTime(newCurrTimeMS, timeDiffMS)
}
}

companion object {
private const val TIMEZONE_KEY = "TIMEZONE"

/**
* Registers timezone change receiver on app start.
* */
fun registerTimeZoneChangeReceiver(context: Context, receiver: BroadcastReceiver) {
Timber.d("Registering Timezone change receiver...")

val filter = IntentFilter(Intent.ACTION_TIMEZONE_CHANGED)
context.registerReceiver(receiver, filter)
}

/**
* Get current time according the timezone of user.
* @return epoch time in milliseconds
* */
fun getZonedCurrTimeMS(zoneId: String): Long {
val currTimeMS = TimeManager.time.intTimeMS()
val offset = TimeZone.getTimeZone(zoneId).getOffset(currTimeMS)
return currTimeMS + offset
}
}
}

0 comments on commit b4d37d9

Please sign in to comment.