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

Asked

Viewed 228 times

2

I’m making an application, where has a job registration in Sqlite that should be synchronized with the server in PHP with Mysql.

After doing a lot of research, I couldn’t find any answers to my question.

I’m basing my synchronization on mode Incremental as this response suggests. /a/146592/97220

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

As I demonstrate in this animation:

inserir a descrição da imagem aqui

So far everything is great and working.

Now my problem is in offline mode and when the connection falls in the middle of synchronization.

For example. I register a new item, create a data version on mobile even when offline. When I connect, I need to know how the app detects that data is still not sent.

And when the data is sent, but the connection falls in the middle of the way. As my application may know that there is still data that need to answer?

The problem would be more or less like in this animation:

inserir a descrição da imagem aqui

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 update response.

Did I understand? I don’t know if I could explain it properly.

My problem is being with logic to solve when this kind of error happens.

I am very grateful if someone can give me a light without negativing me. I don’t know any other way to ask this question.

1 answer

2


You can do a check every X seconds/min/hour to check for internet, and all that is done you save in your Sqlite and creates a column that loads the default non-synchronized state, when that row is sent, you change the status of it, when the user modifies that row again, you change the state again 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 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 send, you also take the server reset and change the status in the Sqlite to show that that line has already been synchronized, but when it changes, you change the state again to not synchronized.

Also you can use the Broadcast or a Service to make this check when the app is already closed and sync before the next time the user opens the app.

Just one thing, the Timer is only canceled if you do:

timer.cancel();

Or if the application dies, otherwise, even with onPause/ onStop it will keep running, it is important this not to let it running at times it is not necessary.

In the case of your question, of the connection falling before receiving the answer that was realized the update, you can save in a table what was changed, and in the answer itself of this change vice for example the id, and when the app received, it sent a new request talking "Look, I’ve identified that everything worked out" and delete this last record, which is what is waiting for the answer back from the app.

When you go to check if you have Internet, if everything goes right the first thing you do is to search if there is any record on your server that awaited your answer and this was not realized. From there you decide what you do with the data.

  • Thanks for the great explanation. I didn’t know this function of time.schedule. But one last question. In this case if for example there is an error on the phone and application close, the timer will be canceled right, as you explained. So I’m thinking of using your tips, but with service. But I’m afraid of being a problem to occupy too much the memory of users with older and weak device, since the service continues running even with the application closed. My question is... Do you have any special tips to use service without taking up too much memory, or is this just my paranoia, and I can do it quietly?

  • 1

    @Samantasilva I think more paranoid, the Service will just do his job and after that you kill him, will not leave him running endlessly, to do this check when the app NAY is open from time to time you can use a AlarmManager, that from time to time is activated if the app NAY is open, you can configure it to work this way, because if with the app open you already use the timer, doesn’t need the Service also, that would spend memoria for nothing

  • Got it, thank you so much for the answers. Helped me a lot. I’ll put in practice. Bjss

Browser other questions tagged

You are not signed in. Login or sign up in order to post.