11

I have app which needs to sync the data as soon as internet is connected on device.

I have the sync work in Worker class and it is working fine. But I need to run this class as soon as internet is connected in phone. As broadcast receiver's on connection change is not recommended and deprecated, I need a way to fire up my class when internet is connected so that the data gets synced. How can I achieve this?

I also thought to schedule the work manager when user exists the app and keep condition of Internet connected but when app is closed from recent the onDestroy is not called. Do you have any solution or logic for this please?

simplegalaxy
  • 135
  • 1
  • 2
  • 6
  • 1
    How you can check here in the Google Docs: https://developer.android.com/topic/libraries/architecture/workmanager -> "WorkManager is intended for tasks that are deferrable—that is, not required to run immediately—and required to run reliably even if the app exits or the device restarts". Which means the request will be executed but maybe not immediately and also the minimum time in PeriodicWorkRequest is 15 min – MrVasilev Sep 29 '19 at 08:47
  • 1
    HI thanks for answer, thanks for this part but I had done this, I have work manager run perfectly but the important thing that I am lacking is that I need to run that work manager when network is connected everytime. So where do I enqueue this request. – simplegalaxy Sep 29 '19 at 09:04

2 Answers2

12

Boy got your point. The thing you pointed out is exactly correct that you should try to avoid the broadcast receivers for such situation as people these day has large number of apps and each app firing request after internet is connected would make user's system freeze as each app want to send request after wifi is connected. Thus android system came with JET PACK after which you should not perform your app's action but request that action to android system and they will handle background request.

As Saeed mentioned above go with

Constraints constraints = new Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED)
                    .build(); 
OneTimeWorkRequest onetimeJob = new OneTimeWorkRequest.Builder(YourJob.class)
                    .setConstraints(constraints).build(); // or PeriodicWorkRequest
WorkManager.getInstance().enqueue(onetimeJob);

But wait, you want to fire the work when internet is connected so you want some kinda thing like deprecated broadcast for connection change. Why don't you do one thing? Whenever the data you get when user is in the foreground or background use fire the work manager. If you are using retrofit for it then on it returns error when there is no internet connection thus you can schedule job when the failure is due to network.

So you work will be

  override fun onFailure(call: Call<Chat>, t: Throwable) {
                 Log.v("chatsyncchecking","sending message failed",t)

                 if(t is IOException){
                     Log.v("chatsyncchecking","scheduling chat sync")
                     (app as App).enqueueChatSync()
                 }
             }

(You can fire every request from application class)

So this make you a benefit that you should not fire work manager whenever the internet is connected. Just you fire when some task fail. This makes less work request to android system too. After all we all are the community to help android improve and users to have great experience with phone no lagging much. Hope it helps

  • 2
    O my, your answer was so fluent that I enjoyed the writing written by a professional documenter. And one more thing I was using retrofit and this helped to gain good idea. – simplegalaxy Sep 29 '19 at 11:46
9

Due to the new restrictions on Android O and above, You can't fire up your class immediately after the network connection is active using manifest flags. But you can tell Workmanager to run your job as soon as any internet connection is available.

To do that you need to define a constraint:

 Constraints constraints = new Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED)
                    .build(); 

And then enqueue your job:

OneTimeWorkRequest onetimeJob = new OneTimeWorkRequest.Builder(YourJob.class)
                    .setConstraints(constraints).build(); // or PeriodicWorkRequest
WorkManager.getInstance().enqueue(onetimeJob);
Saeed Masoumi
  • 8,746
  • 7
  • 57
  • 76
  • 2
    HI thanks for answer, thanks for this part but I had done this, I have work manager run perfectly but the important thing that I am lacking is that I need to run that work manager when network is connected everytime. So where do I enqueue this request. – simplegalaxy Sep 29 '19 at 09:04
  • 1
    @simplegalaxy Do you mean that you want to call this Job every time the network is connected? – Saeed Masoumi Sep 29 '19 at 09:38
  • @SaeedMasoumi With your response, Does the job get called every time the network is connected ? – William Mar 04 '20 at 15:13
  • @simplegalaxy use to need use ```PeriodicWorkRequest``` with network constraints to perform a task periodically. – Mohammed Faiyyaz Khatri Sep 02 '21 at 17:27
  • @SaeedMasoumi Is there any way to trigger the Work by event? Like every time a image is saved to handset? Thanks. – g g Jul 30 '22 at 22:16