Run worker every time user connects to internet

Viewed 242

I want to sync with the server every time the user connects to the internet. So far I have been using WorkManager to do the job with 3-hour intervals and constraints requiring internet-connected. But it is missing the intervals where the device is connected to the internet but the work period is not reached. I want it to run every single time the user connected to the internet.

Below is the sample code I am using:

val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()
    val work = PeriodicWorkRequestBuilder<ExampleWorker>(3, TimeUnit.HOURS)
        .setConstraints(constraints)
        .build()
    val workManager = WorkManager.getInstance(context)
    workManager.enqueueUniquePeriodicWork(UniqueWorkerTag,
    ExistingPeriodicWorkPolicy.KEEP, work)

I have gone through different pages and the only solution I find is to use Firebase JobScheduler but it is now deprecated.

1 Answers

Have you tried using ConnectivityManager ? You can register a ConnectivityManager.NetworkCallback to the connectivityManager. This callback will be triggered whenever the network status changes.

Here is a sample code:

  1. In AndroidManifest.xml file, add
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  1. In your kotlin / java file:
package app.soumicslab.stackoverflow

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.annotation.RequiresApi

class MainActivity : AppCompatActivity() {
    // Constants / Statics
    companion object {
        const val TAG: String = "MainActivity"
    }

    // Variables
    private lateinit var connectivityManager: ConnectivityManager
    private lateinit var networkCallback: ConnectivityManager.NetworkCallback
    private var isInternetAvailableForApiGte21: Boolean = false

    // Override methods
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


    }

    override fun onResume() {
        super.onResume()
        if(!this::connectivityManager.isInitialized) {
            connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            registerNetworkCallBackForApiGte21()
        }
    }

    override fun onPause() {
        super.onPause()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            unregisterNetworkCallBackForApiGte21()
        }
    }

    // Private methods

    @RequiresApi(Build.VERSION_CODES.N)
    private fun registerNetworkCallBackForApiGte21() {
        if(!this::networkCallback.isInitialized) {
            this.networkCallback = object: ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    super.onAvailable(network)
                    isInternetAvailableForApiGte21 = true
                    Log.e(TAG, "networkCallBack onAvailable")

                    // todo: <------Your worker code goes inside here-----

                }

                override fun onLost(network: Network) {
                    super.onLost(network)
                    isInternetAvailableForApiGte21 = false
                    Log.e(TAG, "networkCallBack onLost")
                }
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val looper: Looper = Looper.getMainLooper()
            val handler = Handler(looper)
            this.connectivityManager.registerDefaultNetworkCallback(this.networkCallback, handler)
        }else{
            this.connectivityManager.registerDefaultNetworkCallback(this.networkCallback)
        }
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun unregisterNetworkCallBackForApiGte21() {
        if(this::networkCallback.isInitialized) {
            this.connectivityManager.unregisterNetworkCallback(this.networkCallback)
        }
    }

}

So after running this, I toogled Wi-Fi, mobile data. This is the output in Android Studio's Logcat:

2021-09-21 08:54:38.668 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onAvailable
2021-09-21 08:54:43.284 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onLost
2021-09-21 08:54:48.527 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onAvailable
2021-09-21 08:54:52.782 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onLost
2021-09-21 08:55:04.459 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onAvailable
2021-09-21 08:55:06.685 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onLost
2021-09-21 08:55:10.228 4008-4008/app.soumicslab.stackoverflow E/MainActivity: networkCallBack onAvailable
... ... ...
Related