How to implement AsyncTask when reviewing connectivity?

1

I'm using a method to check the internet connection, the problem is that the activity is momentarily suspended at the time this check is done, that's the verification method I found on the internet:

Try to implement it, but it ended with an object inside the if and I do not know how to do it with a AsyncTask .

if(isAvailable()){
    alert.showAlertDialog(MainActivity.this, "Verifique su conexión!", 
                         "No hay conexión ", false);                    
} else{      
    // hago otra cosa 
}

The isAvaliable() method is as follows:

public Boolean isAvailable() {
    try {
        Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
        int returnVal = p1.waitFor();
        boolean reachable = (returnVal==0);
        if(reachable){
            System.out.println("Internet access");
            // return reachable;
            return false;
        }
        else{
            System.out.println("No Internet access");
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

Thank you in advance for the help.

    
asked by JESUS ESPINOSA 12.03.2016 в 15:42
source

3 answers

2

Since isAvailable() is a synchronous method, you can not do it the same way you do it now, that is, a if .. else ; since you should wait for the asynchronous task to complete before continuing (Although @Elenasys reuses it, of course it can be reused, but this approach is different, it puts everything together).

For you to know, the purpose of AsnycTask is to perform a task in the background, that interacts with the user interface before starting, during its progress and at the end. So there are many options (as you already explained), here we are going to use it, but to show a simple progress dialog so that the user knows that something is happening and what to expect.

This class that I leave below, is re-usable throughout your project. For example before saving the data in the SQLite, you will know if it is necessary or not in each case. You should not use it as an internal class of your Activity but as an independent class.

Code commented:

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import java.io.IOException;

/**
 * Verificar internet y proseguir
 */
public class VerificarInternet extends AsyncTask<Void, Void, Boolean> {

    // esta interface define como se procesara el resultado
    // es una forma personalizada de pasar a la AsyncTask tareas que 
    // debe realizar cuando termine, en este caso tiene 2 métodos,
    // que invocaremos según el resultado del ping.
    public interface EntoncesHacer {
        void cuandoHayInternet();
        void cuandoNOHayInternet();
    }

    // variables necesarias, el dialogo de progreso, el contexto de la actividad
    // y una instancia de EntoncesHacer, donde se ejecutan las acciones.
    private ProgressDialog dialog;
    private Context context;
    private EntoncesHacer accion;

    // Constructor, recibe el contexto de la actividad actual,
    // y la instancia de EntoncesHacer
    public VerificarInternet(Context context, EntoncesHacer accion) {
        this.context = context;
        this.accion = accion;
    }

    // corre en el Thread de la UI antes de empezar la tarea en segundo plano.
    // aquí aprovechamos y mostramos el progress...
    @Override
    protected void onPreExecute() {
        // preparamos el cuadro de dialogo
        dialog = new ProgressDialog(context);
        dialog.setMessage("Verificando conexión a Internet");
        dialog.setCancelable(false);
        dialog.show();

        // llamamos al padre
        super.onPreExecute();
    }

    // Esta es la tarea en segundo plano en si.
    @Override
    protected Boolean doInBackground(Void... arg0) {
        // esta es una version modificada de tu codigo original, pero hace
        // mas o menos lo mismo.
        // la diferencia esta en la forma que invoca a ping, intenta mas 
        // veces y espera mas tiempo.
        // si la conexion a internet esta un poco lenta, el otro mecanismo
        // puede dar falsos negativos, este es un poco mas robusto al 
        // reintentar 2 veces y esperar mas tiempo.
        // si la conexion es normal, sera muy rapid
        Runtime runtime = Runtime.getRuntime();
        try {

            Process ipProcess = runtime.exec("ping -c 2 -w 4 google.com");
            int     exitValue = ipProcess.waitFor();
            return (exitValue == 0);

        } catch (IOException e)          { e.printStackTrace(); }
          catch (InterruptedException e) { e.printStackTrace(); }

        return false;
    }

    // Esta es la tarea a realizar cuando termina la tarea en segundo plano
    // aquí de acuerdo al resultado llamaremos a uno u otro método
    // de la interface EntoncesHacer
    @Override
    protected void onPostExecute(Boolean resultado) {
        // llamamos al padre
        super.onPostExecute(resultado);

        // cerramos el cuadro de progreso
        dialog.dismiss();

        // de acuerdo al resultado del ping, se ejecuta una acción o la otra
        if (resultado) {
            accion.cuandoHayInternet();
        } else {
            accion.cuandoNOHayInternet();
        }
    }
}

Then you have to use it this way:

// aqui creamos la una instancia de VerificarInternet, que recibe el contexto 
// y la interface interna que se utiliza para decidir que hacer de acuerdo 
// a cada resultado.
VerificarInternet tarea =
        new VerificarInternet(NombreActivity.this, new VerificarInternet.EntoncesHacer() {
            @Override
            public void cuandoHayInternet() {
                // abrimos la nueva ventana.. este es el ELSE de tu if
                Intent intent = new Intent(ActividadPrimaria.this, 
                                              ActividadSecundaria.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                ActividadPrimaria.this.startActivity(intent);
            }

            @Override
            public void cuandoNOHayInternet() {
                Toast.makeText(getApplicationContext(), "Lo sentimos no hay internet", 
                                  Toast.LENGTH_LONG).show();
            }
        });
tarea.execute();

Keep in mind that your application should use the following in manifest

 <uses-permission android:name="android.permission.INTERNET" />
    
answered by 12.03.2016 / 22:51
source
1

AsynTask allows you to perform background operations (background) and publish (update) them in the main thread (UI thread).

  

Work with 3 types: Params, Progress and Result.

     

Work in 4 steps: onPreExecute (), doInBackground (Params ...), onProgressUpdate (Progress ...) and OnPostExecute (Result):

Official AsynTask reference: Link

Links of interest in Spanish

A brief example of how to implement it.

private class EjemploAsyncTask extends AsyncTask<Void,Integer,Boolean>{

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // por ejemplo: progressBar.setMax(100); progressBar.setProgress(0);
        // ESTE SE EJECUTA EN EL HILO PRINCIPAL
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        // RECIBES PARAMETROS Y TRATAS TAREA, ESTO SE EJECUTA EN UN HILO APARTE
        // RETORNAS 
       return true;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        // por ejemplo: progressBar.setProgress(values[0].intValue());
        // ESTE SE EJECUTA EN EL HILO PRINCIPAL
    }

    @Override
    protected void onPostExecute(Boolean resultado) {
        super.onPostExecute(resultado);
        // TAREA REALIZADA, ESTO SE EJECUTA EN EL HILO PRINCIPAL
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
        // TAREA ASÍNCRONA CANCELADA
        // ESTE SE EJECUTA EN EL HILO APARTE
    }

}
    
answered by 12.03.2016 в 20:53
1

Asynctask is intended to manage multiple tasks, Threads, in your case you could use only runOnUiThread() , and it would not be so necessary to use a Asynctask :

    MainActivity.this.runOnUiThread(new Runnable() {
        public void run() {

            if(isAvailable()){
                alert.showAlertDialog(MainActivity.this, "Verifique su conexión!", "No      hay conexión ", false);
            } else{
                //....hago otra cosa 
            }

        }

     });

If you choose to use a Asynctask , this would be the implementation:

public class AsyncConnectTask extends AsyncTask<Void, Void, Boolean> {

            @Override
            protected Boolean doInBackground(Void... params) {

           //Ejecutas tu método para comprobar conexión, el cual regresa un valor boleano.
                return isAvailable(); 

            }

            @Override
            protected void onPostExecute(Boolean isAvalable) {

            //Se recibe el valor boleano del método doInBackground().
            // Se puede abrir el Dialogo en el Thread principal. 
                if(isAvalable){     
                     alert.showAlertDialog(MainActivity.this, "Verifique su conexión!", "No      hay conexión ", false);              
                } else{
                    //....hago otra cosa               
                }
            }

            @Override
            protected void onPreExecute() {}

            @Override
            protected void onProgressUpdate(Void... values) {}

        }

To run the Asynctask it would be with:

    new AsyncConnectTask().execute();

Note: Something important to comment is that to detect if you have access to the internet you can do it with the method:

      public static boolean isOnline() {
                NetworkInfo networkInfo = getManager().getActiveNetworkInfo();
                return networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
            }

which you use could fail in some versions of operating system, this method is what I describe in my answer " detect when there Internet available on Android? "

    
answered by 12.03.2016 в 21:45