0

I want to schedule a post to my API that sends logs every couple hours while ensuring there is an internet connection, so for example if I reach the 2 hours and I dont have internet at that moment, I want to wait until there is, send the request and reset the timer to the current sync hour.

I have seen this related issue but doesnt take in consideration the internet connectivity part.

I extended AppCompatActivity to register a BroadcastReceiver in every activity as so:

public class BaseActivity extends AppCompatActivity {

    InternetReceiver internetReceiver = new InternetReceiver();
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(internetReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(internetReceiver);
    }

And my InternetReceiver looks like so:

public class InternetReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
            boolean noConnection = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
            if (!noConnection) {
                // send some data...
            }
        }
    }
}

How can I achieve this?

2 Answers2

0
  1. In that service that is running each hour, check if the device has a connection. If it doesn't add the log data to a "pending" queue, otherwise send the log.

  2. When the broadcast receiver notifies a good connection, send all the logs in the queue.

  3. Clear the queue.

You could even save the queued logs to Shared Preferences or to a Room database so if the app is closed you could save them and check for a connection and send logs on next startup.

Eric
  • 2,573
  • 1
  • 23
  • 19
  • I mostly have trouble on how to aproach the service part. I have give it a thought and maybe using a BroadcastReceiver is not the best choice. But rather check if there is any internet connection inside the service that handles the timing, would using `ScheduledThreadPoolExecutor` be a good idea in that case? – Daniel Hernández Oct 20 '22 at 17:12
  • The BroadcastReceiver will notify the app when the network state changes so you can send up all the offline logs from onReceive. And then in the service that sends the logs, you can check if the device has a network connection to decide whether or not you want to send the log right then or place it in a pending queue. Your service can be as simple as a Retrofit call wrapped in a class, you don't necessarily need to extend the Service class and use AlarmManager but you can. If the app is open all the time and you want to send the logs at an interval it could be simple java Timer at an interval. – Eric Oct 20 '22 at 20:58
  • For checking network connection in the service https://stackoverflow.com/questions/9570237/android-check-internet-connection – Eric Oct 20 '22 at 21:00
0

You can use Android WorkManager for scheduling tasks WorkManager Codelabs

Create worker class

class MyWorker(appContext: Context, workerParams: WorkerParameters) :Worker(appContext, workerParams) {
    override fun doWork(): Result {
        //do task
        return Result.success()
    }
}

Consume it

val myWorkerRequest: WorkRequest =
            PeriodicWorkRequestBuilder<MyWorker>(10, TimeUnit.SECONDS)
.setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()).build()
            WorkManager.getInstance(requireContext()).enqueue(myWorkerRequest)
Adin D
  • 61
  • 4