Android service runs only the first time

3

I'm developing an application where synchronization with web services is done. The application is very simple, it makes a list of questions, the user responds, clicking on finalizes, writes this data in the cellular database, and does the replication, since it may or may not be connected to the internet.

My problem is next, the first time I open the system and do the whole process, everything works perfectly, synchronizes, launches the pro notification cell, does everything right and returns to the screen to start a new process.

The second time it is done, it is written to the mobile database, but it does not synchronize, it seems the service simply does not run.

When I close the system, clean it from memory, then the synchronization is done. I've done several tests and so far I have not been able to solve them.

Follow the codes:

public void finalizaCheckList(){
    ContentValues ctvResposta = new ContentValues();
    ctvResposta.put("status",1);
    SQLiteDatabase dbResposta = openOrCreateDatabase("respostas.db", Context.MODE_PRIVATE, null);
    long iCodigoResposta = dbResposta.insert("respostas","_id",ctvResposta);
    dbResposta.close();


    for (int i = 0; i < alR.size(); i++){
        RadioGroup rgResposta = alR.get(i);
        int handleItemSelecionado = rgResposta.getId();
        int itenSelecionado =   rgResposta.indexOfChild(findViewById(rgResposta.getCheckedRadioButtonId()));

        ContentValues ctv = new ContentValues();
        ctv.put("placa",placa);
        ctv.put("placanumero",_placanumero);
        ctv.put("handle_checklist",handle_checklist);
        ctv.put("tipopergunta",1);
        ctv.put("handle_checklist_pergunta",handleItemSelecionado);
        if (itenSelecionado == 0){
            ctv.put("resposta","S");
        } else {
            ctv.put("resposta","N");
        }
        ctv.put("usuario",handle_usuario);
        ctv.put("sincronizado",1);
        ctv.put("codigo_resposta",iCodigoResposta);

        SQLiteDatabase db1 = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
        db1.insert("checklist_resposta","_id",ctv);
        db1.close();
    }


    for (int ii = 0; ii < alE.size(); ii++){
        EditText edResposta = alE.get(ii);

        int handleItemSelecionado = edResposta.getId();
        String resposta = edResposta.getText().toString();

        ContentValues ctv = new ContentValues();
        ctv.put("placa",placa);
        ctv.put("placanumero",_placanumero);
        ctv.put("handle_checklist",handle_checklist);
        ctv.put("tipopergunta",2);
        ctv.put("handle_checklist_pergunta",handleItemSelecionado);
        ctv.put("resposta",resposta);
        ctv.put("usuario",handle_usuario);
        ctv.put("sincronizado",1);
        ctv.put("codigo_resposta",iCodigoResposta);

        SQLiteDatabase db1 = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
        db1.insert("checklist_resposta","_id",ctv);
        db1.close();
    }

    Intent intent = new Intent("br.cooper.system.checklist.ReplicarCheckLists") ;
    this.startService(intent) ;
}

File AndroidManifest.xml :

<service android:name="br.cooper.system.checklist.ReplicarCheckLists"
        android:enabled="true"
        android:process=":remote">
        <intent-filter >
            <action android:name="br.cooper.system.checklist.ReplicarCheckLists"/>
        </intent-filter>
    </service>

My replication code:

public class ReplicarCheckLists extends Service implements Runnable {
private Handler mainHandler;
private Handler handler;
private String sXML = "";

@Override
public void onCreate(){
    if (verificaConexao()){
        new Thread(ReplicarCheckLists.this).start();
    }
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
}
@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public void run() {
    Looper.prepare();
    handler = new Handler();

    boolean post = handler.post(new Runnable() {
        @Override
        public void run() {
            //Criado para ser gerado quando for disparado a Thread
            SQLiteDatabase sqlRespostas = openOrCreateDatabase("respostas.db",Context.MODE_PRIVATE, null);
            Cursor cursorResposta = sqlRespostas.rawQuery("select _id from respostas where status = 1",null);

            SQLiteDatabase sqlSincronizado = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
            Cursor cursorR = sqlSincronizado.rawQuery("select placanumero from checklist_resposta group by placanumero", null);

            try {
                SQLiteDatabase sql = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
                Cursor cursor = null;
                Cursor cursorAtualizacao = sql.rawQuery("select _id, handle_checklist, placa, handle_checklist_pergunta, tipopergunta, usuario, resposta, placanumero, handle_checklist  from checklist_resposta where sincronizado = 1", null);

                SincronizaRespostas sincrona = new SincronizaRespostas();
                String sResposta = "";

                boolean bCabacalho = false;
                while (cursorResposta.moveToNext()){
                    cursor = sql.rawQuery("select _id, handle_checklist, placa, handle_checklist_pergunta, tipopergunta, usuario, resposta, placanumero, handle_checklist  " +
                            "from checklist_resposta where sincronizado = 1 " +
                            "and codigo_resposta =  " + cursorResposta.getString(cursorResposta.getColumnIndex("_id")) , null);
                    while (cursor.moveToNext()) {
                        if (!bCabacalho) {
                            geraXML("respostachecklist", "", false);
                            geraXML("placa", cursor.getString(cursor.getColumnIndex("placa")), false);
                            geraXML("checklist", cursor.getString(cursor.getColumnIndex("handle_checklist")), false);
                            geraXML("usuario", cursor.getString(cursor.getColumnIndex("usuario")), false);

                            bCabacalho = true;
                        }

                        geraXML("respostas","",false);
                        geraXML("pergunta", cursor.getString(cursor.getColumnIndex("handle_checklist_pergunta")), false);
                        geraXML("tipopergunta",cursor.getString(cursor.getColumnIndex("tipopergunta")),false);
                        geraXML("resposta",cursor.getString(cursor.getColumnIndex("resposta")),false);
                        geraXML("respostas", "", true);
                    }
                    geraXML("respostachecklist","",true);



                    if (sincrona.sincoriza(sXML).equals("OK")) {
                        gravaItemOk(cursorResposta.getInt(cursorResposta.getColumnIndex("_id")));
                    }
                    cursor.close();

                }

                sqlSincronizado.close();
                cursor.close();
                cursorAtualizacao.close();
                cursorR.close();
                sql.close();

            } catch (Exception ex) {
                notificacao(cursorR.getString(cursorR.getColumnIndex("placanumero")), true);
                Log.d("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", ex.getMessage());
            }


        }
    });
    Looper.loop();
    stopSelf();


}

I do not know if I could make myself understood, but the problem seems to be simple, but the solution has not yet been found. I do not know if anyone has ever been through this !!

Update

I ran a test using AsyncTask . The code looks like this:

public class ReplicarCheckLists extends Service {
private Handler mainHandler;
private Handler handler;
private String sXML = "";


@Override
public void onCreate(){
    super.onCreate();
    // Migra a lógica de sincronização para o handleCommand
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    handleCommand();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    handleCommand();
    return super.onStartCommand(intent, flags, startId);
}

public void handleCommand() {
    // Inicia uma nova AsyncTask para realizar as operações fora da Main Thread
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            //Criado para ser gerado quando for disparado a Thread
            SQLiteDatabase sqlRespostas = openOrCreateDatabase("respostas.db",Context.MODE_PRIVATE, null);
            Cursor cursorResposta = sqlRespostas.rawQuery("select _id, placa from respostas where status = 1",null);

            String sPlacaNumero = "";

            try {
                SQLiteDatabase sql = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
                Cursor cursor = null;

                SincronizaRespostas sincrona = new SincronizaRespostas();


                boolean bCabacalho = false;
                while (cursorResposta.moveToNext()){
                    sPlacaNumero = cursorResposta.getString(cursorResposta.getColumnIndex("placa"));
                    cursor = sql.rawQuery("select _id, handle_checklist, placa, handle_checklist_pergunta, tipopergunta, usuario, resposta, placanumero, handle_checklist  " +
                            "from checklist_resposta where sincronizado = 1 " +
                            "and codigo_resposta =  " + cursorResposta.getString(cursorResposta.getColumnIndex("_id")) , null);


                    while (cursor.moveToNext()) {
                        if (!bCabacalho) {
                            geraXML("respostachecklist", "", false);
                            geraXML("placa", cursor.getString(cursor.getColumnIndex("placa")), false);
                            geraXML("checklist", cursor.getString(cursor.getColumnIndex("handle_checklist")), false);
                            geraXML("usuario", cursor.getString(cursor.getColumnIndex("usuario")), false);

                            bCabacalho = true;
                        }

                        geraXML("respostas","",false);
                        geraXML("pergunta", cursor.getString(cursor.getColumnIndex("handle_checklist_pergunta")), false);
                        geraXML("tipopergunta",cursor.getString(cursor.getColumnIndex("tipopergunta")),false);
                        geraXML("resposta",cursor.getString(cursor.getColumnIndex("resposta")),false);
                        geraXML("respostas", "", true);
                    }

                    geraXML("respostachecklist","",true);

                    if (sincrona.sincoriza(sXML).equals("OK")) {
                        gravaItemOk(cursorResposta.getInt(cursorResposta.getColumnIndex("_id")));
                        notificacao(sPlacaNumero, false);
                    } else {
                        notificacao(sPlacaNumero, true);
                    }

                }


                cursorResposta.close();
                sql.close();
            } catch (Exception ex) {
                Log.d("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", ex.getMessage());
            }
            return null;
        }
    }.execute();
}

@Override
public void onDestroy() {
    super.onDestroy();
}

However, the following error occurs:

  

22856-23026 / br.cooper.system.checklist: remote D / DDDDDDDDDDDDDDDDDDDDDDDDDDDDD: println needs a message

I do not know what it can be, because this error is a try-catch .

And continue synchronizing after closing the application in total.

Anything else I might be doing to solve this problem?

    
asked by anonymous 28.06.2014 / 17:34

3 answers

0

After so much forcing an attempt at success, I think I've figured out what might be, in fact an alternative that I do not know is the right one, but apparently it worked, I simply forced the service to stop:

Intent intent = new Intent("br.cooper.system.checklist.ReplicarCheckLists") ;
    stopService(intent) ;

If you have any problems that someone else has already been using this way! ??!

Thank you

    
01.07.2014 / 02:59
2

I wondered what the error might be and how it was done, although not recommended, it works (in theory).

Looking at your code, it should recreate Service (calling onCreate ) every time it calls startService , I have no idea why exactly. My hypothesis is that it should be reusing the same instance and so it does not call onCreate even calling stopSelf() .

If you allow me, I suggest a refactoring in your code.

Instead of using onCreate to make its synchronization logic, use onStartCommand (it is recommended in versions above SDK 5) to do its logic.

Also, since you're using Threads , you've even looked at AsyncTask . ? It is a layer that facilitates the manipulation of Threads and updating of the UI. I know it has no UI involved, but that's the trick.

Another modification would be to stop implementing the Runnable interface and using an < AsyncTask anonymous , even if it does not have UI, to facilitate the code.

It would look something like:

public class ReplicarCheckLists extends Service {
    private Handler mainHandler;
    private Handler handler;
    private String sXML = "";

    @Override
    public void onCreate(){
        super.onCreate();
        // Migra a lógica de sincronização para o handleCommand
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        handleCommand();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleCommand();
        return super.onStartCommand(intent, flags, startId);
    }

    public void handleCommand() {
        // Inicia uma nova AsyncTask para realizar as operações fora da Main Thread

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected void doInBackground(Void... params) {
                //Criado para ser gerado quando for disparado a Thread
                SQLiteDatabase sqlRespostas = openOrCreateDatabase("respostas.db",Context.MODE_PRIVATE, null);
                Cursor cursorResposta = sqlRespostas.rawQuery("select _id from respostas where status = 1",null);

                SQLiteDatabase sqlSincronizado = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
                Cursor cursorR = sqlSincronizado.rawQuery("select placanumero from checklist_resposta group by placanumero", null);

                try {
                    SQLiteDatabase sql = openOrCreateDatabase("checklist_resposta.db", Context.MODE_PRIVATE, null);
                    Cursor cursor = null;
                    Cursor cursorAtualizacao = sql.rawQuery("select _id, handle_checklist, placa, handle_checklist_pergunta, tipopergunta, usuario, resposta, placanumero, handle_checklist  from checklist_resposta where sincronizado = 1", null);

                    SincronizaRespostas sincrona = new SincronizaRespostas();
                    String sResposta = "";

                    boolean bCabacalho = false;
                    while (cursorResposta.moveToNext()){
                        cursor = sql.rawQuery("select _id, handle_checklist, placa, handle_checklist_pergunta, tipopergunta, usuario, resposta, placanumero, handle_checklist  " +
                                              "from checklist_resposta where sincronizado = 1 " +
                                              "and codigo_resposta =  " + cursorResposta.getString(cursorResposta.getColumnIndex("_id")) , null);

                        while (cursor.moveToNext()) {
                            if (!bCabacalho) {
                                geraXML("respostachecklist", "", false);
                                geraXML("placa", cursor.getString(cursor.getColumnIndex("placa")), false);
                                geraXML("checklist", cursor.getString(cursor.getColumnIndex("handle_checklist")), false);
                                geraXML("usuario", cursor.getString(cursor.getColumnIndex("usuario")), false);

                                bCabacalho = true;
                            }

                            geraXML("respostas","",false);
                            geraXML("pergunta", cursor.getString(cursor.getColumnIndex("handle_checklist_pergunta")), false);
                            geraXML("tipopergunta",cursor.getString(cursor.getColumnIndex("tipopergunta")),false);
                            geraXML("resposta",cursor.getString(cursor.getColumnIndex("resposta")),false);
                            geraXML("respostas", "", true);
                        }

                        geraXML("respostachecklist","",true);

                        if (sincrona.sincoriza(sXML).equals("OK")) {
                            gravaItemOk(cursorResposta.getInt(cursorResposta.getColumnIndex("_id")));
                        }

                        cursor.close();
                    }

                    sqlSincronizado.close();
                    cursor.close();
                    cursorAtualizacao.close();
                    cursorR.close();
                    sql.close();
                } catch (Exception ex) {
                    notificacao(cursorR.getString(cursorR.getColumnIndex("placanumero")), true);
                    Log.d("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", ex.getMessage());
                }
            }
        }.execute();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
    
28.06.2014 / 18:44
0

Put this implementation in your service:

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
{


   // Este flag faz com que o sistema restart o serviço caso seja parado, tanto pelo
   //usuário como pelo sistema. Só o aplicativo poderá pará-lo
    return START_STICKY;

}
    
30.06.2014 / 23:40