Data sync to remote servers with Android's WorkManager.

Implemented background syncing for 15 min interval for testing.
Tested and confirmed process.
This commit is contained in:
2024-09-13 20:53:18 +05:30
parent cbab2ee805
commit 1e1531a14b
5 changed files with 77 additions and 14 deletions

View File

@@ -131,6 +131,9 @@ dependencies {
// admob // admob
implementation(libs.play.services.ads) implementation(libs.play.services.ads)
// work manager
implementation libs.androidx.work.runtime.ktx
implementation libs.firebase.analytics implementation libs.firebase.analytics
implementation libs.firebase.perf implementation libs.firebase.perf

View File

@@ -2,13 +2,17 @@ package com.woka
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Application import android.app.Application
import android.util.Log import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.google.android.gms.ads.MobileAds import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.RequestConfiguration
import com.jwplayer.pub.api.license.LicenseUtil import com.jwplayer.pub.api.license.LicenseUtil
import com.onesignal.OneSignal import com.onesignal.OneSignal
import com.woka.advertisements.AdsRepository import com.woka.advertisements.AdsRepository
import com.woka.database.AppDatabase import com.woka.database.AppDatabase
import com.woka.database.helpers.SyncWorker
import com.woka.streamingurls.StreamingUrlRepository import com.woka.streamingurls.StreamingUrlRepository
import com.woka.userPreference.UserPreference import com.woka.userPreference.UserPreference
import com.woka.utils.JW_PLAYER_LICENSE import com.woka.utils.JW_PLAYER_LICENSE
@@ -16,14 +20,18 @@ import com.woka.utils.ONESIGNAL_APP_ID
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Arrays import java.util.concurrent.TimeUnit
class WokaApp: Application() { class WokaApp : Application() {
companion object{ companion object {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
var userPrefs: UserPreference? = null var userPrefs: UserPreference? = null
var appDatabase: AppDatabase? = null var appDatabase: AppDatabase? = null
private const val LOCAL_DATA_SYNC_WORK = "com.woka.LOCAL_DATA_SYNC"
private const val LOCAL_DATA_SYNC_PERIODIC_TIME_INTERVAL = 15L
private val LOCAL_DATA_SYNC_PERIODIC_TIME_INTERVAL_UNIT = TimeUnit.MINUTES
} }
override fun onCreate() { override fun onCreate() {
@@ -42,9 +50,11 @@ class WokaApp: Application() {
initOneSignal() initOneSignal()
initAdmob() initAdmob()
dataSyncWorkRequest()
} }
private fun initOneSignal(){ private fun initOneSignal() {
// OneSignal Initialization // OneSignal Initialization
OneSignal.initWithContext(this, ONESIGNAL_APP_ID) OneSignal.initWithContext(this, ONESIGNAL_APP_ID)
@@ -55,10 +65,27 @@ class WokaApp: Application() {
} }
} }
private fun initAdmob(){ private fun initAdmob() {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
MobileAds.initialize(this@WokaApp) MobileAds.initialize(this@WokaApp)
// MobileAds.setRequestConfiguration(RequestConfiguration.Builder().setTestDeviceIds(listOf("F895DC452659EA607EB688E47B041B20")).build())
} }
} }
private fun dataSyncWorkRequest() {
WorkManager.getInstance(this)
.enqueueUniquePeriodicWork(
LOCAL_DATA_SYNC_WORK,
ExistingPeriodicWorkPolicy.KEEP,
PeriodicWorkRequestBuilder<SyncWorker>(
LOCAL_DATA_SYNC_PERIODIC_TIME_INTERVAL,
LOCAL_DATA_SYNC_PERIODIC_TIME_INTERVAL_UNIT, // Every day
)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) // only when the internet is available
.build()
)
.build()
)
}
} }

View File

@@ -0,0 +1,28 @@
package com.woka.database.helpers
import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
class SyncWorker(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {
companion object {
private const val TAG = "LocalDataSyncWorker"
}
override suspend fun doWork(): Result {
return try {
Log.d(TAG, "doWork: WORK IN PROGRESS..")
RemoteSync.syncClickEvents()
RemoteSync.syncAdClickEvents()
Log.d(TAG, "doWork: WORK WAS SUCCESSFUL")
Result.success()
} catch (t: Throwable) {
Log.e(TAG, "doWork: WORK FAILED", t)
Result.retry()
}
}
}

View File

@@ -75,6 +75,8 @@ import com.woka.utils.lightStatusBar
import com.woka.utils.setVisibility import com.woka.utils.setVisibility
import com.woka.utils.show import com.woka.utils.show
import com.woka.utils.toast import com.woka.utils.toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.min import kotlin.math.min
@@ -163,12 +165,8 @@ class HomeActivity : WokaBaseActivity(),
decisionDialog.message = getString(R.string.do_you_want_to_exit_from_the_woka_app) decisionDialog.message = getString(R.string.do_you_want_to_exit_from_the_woka_app)
decisionDialog.setPositiveButton(getString(R.string.yes)){ decisionDialog.setPositiveButton(getString(R.string.yes)){
lifecycleScope.launch { @Suppress("DEPRECATION")
RemoteSync.syncClickEvents() super.onBackPressed()
RemoteSync.syncAdClickEvents()
@Suppress("DEPRECATION")
super.onBackPressed()
}
} }
decisionDialog.setNegativeButton(getString(R.string.no)) decisionDialog.setNegativeButton(getString(R.string.no))
@@ -188,6 +186,11 @@ class HomeActivity : WokaBaseActivity(),
} }
(getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager).unregisterNetworkCallback(networkCallback) (getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager).unregisterNetworkCallback(networkCallback)
CoroutineScope(Dispatchers.IO).launch {
RemoteSync.syncClickEvents()
RemoteSync.syncAdClickEvents()
}
} }
private fun setObservers(){ private fun setObservers(){

View File

@@ -39,6 +39,7 @@ perfPlugin = "1.4.2"
sdpAndroid = "1.1.1" sdpAndroid = "1.1.1"
shimmer = "0.5.0" shimmer = "0.5.0"
sspAndroid = "1.1.1" sspAndroid = "1.1.1"
workRuntimeKtx = "2.9.1"
[libraries] [libraries]
android_audio_mixer = { module = "com.github.ZeroOneZeroR:android_audio_mixer", version.ref = "android_audio_mixer" } android_audio_mixer = { module = "com.github.ZeroOneZeroR:android_audio_mixer", version.ref = "android_audio_mixer" }
@@ -58,6 +59,7 @@ androidx-media3-exoplayer-smoothstreaming = { module = "androidx.media3:media3-e
androidx-media3-extractor = { module = "androidx.media3:media3-extractor", version.ref = "media3Exoplayer" } androidx-media3-extractor = { module = "androidx.media3:media3-extractor", version.ref = "media3Exoplayer" }
androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3Exoplayer" } androidx-media3-ui = { module = "androidx.media3:media3-ui", version.ref = "media3Exoplayer" }
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomRuntime" }
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "workRuntimeKtx" }
circleimageview = { module = "de.hdodenhof:circleimageview", version.ref = "circleimageview" } circleimageview = { module = "de.hdodenhof:circleimageview", version.ref = "circleimageview" }
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" } converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }