diff --git a/AnkiDroid/build.gradle b/AnkiDroid/build.gradle
index d22c131cb026..2116177bdc9e 100644
--- a/AnkiDroid/build.gradle
+++ b/AnkiDroid/build.gradle
@@ -329,9 +329,6 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:rules:1.4.0'
- // GSON
- implementation 'com.google.code.gson:gson:2.9.0'
-
// Work Manager
implementation "androidx.work:work-runtime-ktx:2.7.1"
}
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java
index a36719d2caeb..6b580ea8f2a3 100644
--- a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.java
@@ -428,7 +428,7 @@ public static String getWebViewErrorMessage() {
private void setupDeckMetaDataWorker() {
Timber.tag("META").e("Setting up deck meta data worker...");
- PeriodicWorkRequest deckMetaDataWorker = new PeriodicWorkRequest.Builder(DeckMetaDataWorker.class, 2, TimeUnit.MINUTES)
+ PeriodicWorkRequest deckMetaDataWorker = new PeriodicWorkRequest.Builder(DeckMetaDataWorker.class, 30, TimeUnit.MINUTES)
.addTag(DeckMetaDataWorker.DECK_META_WORKER)
.build();
@@ -438,6 +438,9 @@ private void setupDeckMetaDataWorker() {
ExistingPeriodicWorkPolicy.REPLACE,
deckMetaDataWorker
);
+
+ // Does the required work in setting up new Worker.
+ DeckMetaDataWorker.Companion.setupNewWorker(this);
}
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckMetaDataPreference.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckMetaDataPreference.kt
index b10cea04c7b5..9322a5913782 100644
--- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckMetaDataPreference.kt
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckMetaDataPreference.kt
@@ -18,8 +18,10 @@ package com.ichi2.anki
import android.content.Context
import android.content.SharedPreferences
-import com.google.gson.Gson
+import androidx.core.content.edit
import com.ichi2.anki.worker.DeckMetaDataWorker
+import com.ichi2.utils.JSONException
+import com.ichi2.utils.JSONObject
import timber.log.Timber
class DeckMetaDataPreference(context: Context) {
@@ -27,24 +29,82 @@ class DeckMetaDataPreference(context: Context) {
private val sharedPreferences: SharedPreferences =
context.getSharedPreferences("DeckMetaData", Context.MODE_PRIVATE)
+ /**
+ * Use this to store data in shared preference.
+ * @param key The Key of value. Used in fetching the data.
+ * @param value Value that needs to be stored (VALUE MUST BE STRING).
+ * */
fun putString(key: String, value: String) {
- sharedPreferences.edit()
- .putString(key, value)
- .apply()
+ sharedPreferences.edit {
+ putString(key, value)
+ apply()
+ }
}
+ /**
+ * Use this to fetch string from shared preference.
+ * @prams The Key of deck whose data you want to fetch.
+ * @return Value that needs to be fetched (VALUE WILL BE STRING).
+ * */
fun getString(key: String, default: String): String {
return sharedPreferences.getString(key, default)!!
}
+ /**
+ * Use this to store int in shared preference.
+ * @param key The Key of value. Created while storing the data.
+ * @param value Value that needs to be stored (VALUE MUST BE INTEGER).
+ * */
+ fun putInt(key: String, value: Int) {
+ sharedPreferences.edit {
+ putInt(key, value)
+ apply()
+ }
+ }
+
+ /**
+ * Use this to fetch integer from shared preference.
+ * @prams The Key of deck whose data you want to fetch.
+ * @return Value that needs to be fetched (VALUE WILL BE INTEGER).
+ * */
+ fun getInt(key: String, default: Int): Int {
+ return sharedPreferences.getInt(key, default)
+ }
+
+ /**
+ * Use this to store meta data in shared preference.
+ * @param key The Key of deck whose data you want to fetch. (deck id is the for deck)
+ * @param value Object of Metadata Model
+ * */
fun setMetaData(key: String, value: DeckMetaDataWorker.Meta) {
- val json: String = Gson().toJson(value)
- sharedPreferences.edit()
- .putString(key, json)
- .apply()
+ val jsonObject = JSONObject()
+
+ try {
+ jsonObject.put("did", value.did)
+ jsonObject.put("deckName", value.deckName)
+ jsonObject.put("new", value.new)
+ jsonObject.put("lrn", value.lrn)
+ jsonObject.put("rev", value.rev)
+ jsonObject.put("eta", value.eta)
+ } catch (e: JSONException) {
+ Timber.tag("META").e(e)
+ return
+ }
+
+ val json = jsonObject.toString()
+
+ sharedPreferences.edit {
+ putString(key, json)
+ apply()
+ }
Timber.tag("META").e(json)
}
+ /**
+ * Use this to fetch meta data from shared preference if Deck ID (did) is known.
+ * @prams The Key of deck whose data you want to fetch. (deck id is the for deck)
+ * @return Object of Metadata Model.
+ * */
fun getMetaData(key: String): DeckMetaDataWorker.Meta? {
val jsonData = sharedPreferences
.getString(key, null)
@@ -52,7 +112,15 @@ class DeckMetaDataPreference(context: Context) {
return if (jsonData == null) {
null
} else {
- Gson().fromJson(jsonData, DeckMetaDataWorker.Meta::class.java)
+ val jsonObject = JSONObject(jsonData)
+ return DeckMetaDataWorker.Meta(
+ jsonObject.getLong("did"),
+ jsonObject.getString("deckName"),
+ jsonObject.getInt("new"),
+ jsonObject.getInt("lrn"),
+ jsonObject.getInt("rev"),
+ jsonObject.getInt("eta"),
+ )
}
}
}
diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/worker/DeckMetaDataWorker.kt b/AnkiDroid/src/main/java/com/ichi2/anki/worker/DeckMetaDataWorker.kt
index fb4a53bca815..9e3d24952cdd 100644
--- a/AnkiDroid/src/main/java/com/ichi2/anki/worker/DeckMetaDataWorker.kt
+++ b/AnkiDroid/src/main/java/com/ichi2/anki/worker/DeckMetaDataWorker.kt
@@ -21,7 +21,9 @@ import androidx.work.Worker
import androidx.work.WorkerParameters
import com.ichi2.anki.CollectionHelper
import com.ichi2.anki.DeckMetaDataPreference
+import com.ichi2.libanki.Collection
import com.ichi2.libanki.sched.Counts
+import com.ichi2.libanki.sched.DeckDueTreeNode
import timber.log.Timber
/**
@@ -31,18 +33,27 @@ import timber.log.Timber
* */
class DeckMetaDataWorker(val context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {
- private lateinit var colHelper: CollectionHelper
+ // Lambda to check the collection is not null.
+ private val mCollection: (context: Context) -> Collection? = {
+ val collection = CollectionHelper.getInstance()
+ if (collection.getColSafe(it) != null) {
+ collection.getCol(it)
+ } else {
+ null
+ }
+ }
override fun doWork(): Result {
- colHelper = CollectionHelper.getInstance()
+ val date = CollectionHelper.getInstance().getTimeSafe(context).currentDate
- Timber.tag("META").e("Deck Meta Data Worker started at: ${colHelper.getTimeSafe(context).currentDate}")
+ Timber.tag("META").e("Deck Meta Data Worker started at: $date")
// Update the data of Deck Metadata from HERE
- val col = colHelper.getCol(context)
- val deckList = col.sched.deckDueList()
+ val deckList: List =
+ mCollection(context)?.sched?.deckDueList() ?: return Result.failure()
+ val sched = mCollection(context)?.sched ?: return Result.failure()
deckList.forEach {
val new = it?.newCount ?: -1
val lrn = it?.lrnCount ?: -1
@@ -53,12 +64,12 @@ class DeckMetaDataWorker(val context: Context, workerParameters: WorkerParameter
new,
lrn,
rev,
- col.sched.eta(Counts(new, lrn, rev), false)
+ sched.eta(Counts(new, lrn, rev), false)
)
storeInPreference(data)
}
- updateLastFetch(colHelper.getTimeSafe(context).toString())
+ updateLastFetch(date.toString())
return Result.success() // Done work successfully...
}
@@ -66,6 +77,8 @@ class DeckMetaDataWorker(val context: Context, workerParameters: WorkerParameter
private fun updateLastFetch(time: String) {
val metaPreference = DeckMetaDataPreference(context)
metaPreference.putString(LAST_FETCH_TIME, time)
+ val prevData = metaPreference.getInt(TIMES_FETCHED, 0)
+ metaPreference.putInt(TIMES_FETCHED, prevData + 1)
}
/**
@@ -74,6 +87,8 @@ class DeckMetaDataWorker(val context: Context, workerParameters: WorkerParameter
private fun storeInPreference(list: Meta) {
val metaPreference = DeckMetaDataPreference(context)
metaPreference.setMetaData(list.did.toString(), list)
+ val data = metaPreference.getMetaData(list.did.toString())
+ data.toString()
}
data class Meta(
@@ -88,5 +103,17 @@ class DeckMetaDataWorker(val context: Context, workerParameters: WorkerParameter
companion object {
const val DECK_META_WORKER = "DeckMetaData"
const val LAST_FETCH_TIME = "LAST_FETCH"
+ const val TIMES_FETCHED = "TIMES_FETCHED"
+ const val WORKER_CREATED = "WORKER_CREATED"
+
+ fun setupNewWorker(context: Context) {
+ Timber.tag("META").e("Setting up Preference for new Worker.")
+
+ val time = CollectionHelper.getInstance().getTimeSafe(context)
+
+ val metaDataPreference = DeckMetaDataPreference(context)
+ metaDataPreference.putString(WORKER_CREATED, time.currentDate.toString())
+ metaDataPreference.putInt(TIMES_FETCHED, 0)
+ }
}
}