How to resolve a synchronization with the server when there is a connection crash on Android?

2

I'm doing an application, where it has a jobs registry in SQLite that should be synchronized with the server in PHP with Mysql.

After searching a lot, I could not find any answers that solve my question.

I'm basing my sync on Incremental mode as this answer suggests. link

So for example, when the user finishes the registration, the application inserts the data into Sqlite, and creates a data version, and at the same time already tries to communicate with the server to send the inserted data. When it arrives on the server PHP queries if the version is newer, and changes the data and sends the completion response to the application.

Just as you demonstrate in this animation:

Sofareverythingisfineandworking.

Nowmyproblemisinofflinemodeandwhentheconnectiondropsinthemiddleofthesynchronization.

Forexample.Iregisteranewitem,IcreateaversionofdataonmymobileevenwhenI'moffline.WhenIconnect,Ineedtoknowhowtheapplicationdetectsthatthereisstilldatathatwasnotsent.

Andwhenthedataissent,buttheconnectionfallsinthemiddleofthepath.Howcanmyapplicationknowthatdatastillneedstobeanswered?

Theproblemwouldlooksomethinglikethis:

And, after the crash, the application will not be able to try to enter the data again, because the version on the server will already be updated, and will not return an update response.

Did you understand? I do not know if I could explain it correctly.

My problem is being logically resolved when this type of error occurs.

I am very grateful if someone can give me a light without negativizing me. I do not know another way to ask this question.

    
asked by anonymous 30.08.2018 / 08:33

1 answer

2

You can do a check every X seconds / min / hour to check for the internet, and everything you do is saved to your SQLite and creates a column that loads the default state of no synchronized, when that line is sent, you change the status of it, when the user modifies that line again, you change the state back to non-synchronized.

To do this check from time to time you can use:

Timer time = new Timer();
time.schedule(new Verifica(context), 0, intervalo_de_verificação);

In the class you do:

private class Verifica extends TimerTask{
    private Context context;

    public Verifica(Context c){
        this.context = c;
    }

    @override
    public void run(){
       if(conect(context)){
            //Verifico o que mudou após a ultima verificação e mando pro servidor
       }else{
            //Salvo que ainda não tenho internet
       }
    }

    private boolean conect(Context context){
        ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo networkInfo = null;
        if (connMgr != null) {
            networkInfo = connMgr.getActiveNetworkInfo();
        }

        return networkInfo != null && networkInfo.isConnected();
    }
}

In the method you submit, you also get the server response and change the status in the SQLite record to show that the line has already been synchronized, but at the time it changes, you changes the state back to non-synchronized.

You can also use Broadcast or a Service to do this when the application is already closed and sync before the next time the user opens the app.

Only one thing, Timer is only canceled if you do:

timer.cancel();

Or if the application dies, otherwise even with onPause / onStop it will continue to run, so it is important not to let it run at times when it is not needed.

In the case of your question, the connection drops before receiving the response that the update was accomplished, you can save in a table what has changed, and in the response itself of vice change for example the id, and when the app received , it would send a new request saying "look, I already identified that everything worked out" and excludes this last record, which is what is waiting for the response back from the app.

When you go to check if you have Internet, if everything works out the first thing you do is look for if there is a record on your server that expected your answer and it did not materialize. From there you decide what you do with the data.

    
30.08.2018 / 09:14