Check connection at every instant

Asked

Viewed 190 times

2

The thing is, I’m creating an app that depends on the internet connection for most services. To make it more dynamic, I thought I’d do something similar to the Youtube app. In the youtube app it warns almost instantly that the app is disconnected. See:

inserir a descrição da imagem aqui

I did a general search and tried to make use of Threads in two ways:

1. Executor + Runnable

      class ThreadInfinity implements Executor {

            @Override
           public void execute(@NonNull Runnable r) {

                while (true) {
                    r.run();
                }

            }
        }

        Thread r = new Thread(new Runnable() {
            @Override
            public void run() {

                    if (manager.getActiveNetworkInfo() != null && manager.getActiveNetworkInfo().isConnectedOrConnecting()) {

                         Toast.makeText(getApplicationContext(), "Você está conectado", Toast.LENGTH_SHORT);

                    } else {

                         Toast.makeText(getApplicationContext(), "Você está desconectado", Toast.LENGTH_SHORT);

                    }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        ThreadInfinity t = new ThreadInfinity();
        t.execute(r);

2. Asynctask

        Context context = getApplicationContext();
        final ConnectivityManager manager = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE);

        class TheadInfinity extends AsyncTask<Void, Void, Void> {
            protected Void doInBackground(Void... params) {
                while (true)
                    try {
                        if (manager.getActiveNetworkInfo() != null && manager.getActiveNetworkInfo().isConnectedOrConnecting()) {

                             Toast.makeText(getApplicationContext(), "Você está conectado", Toast.LENGTH_SHORT);

                        } else {

                             Toast.makeText(getApplicationContext(), "Você está desconectado", Toast.LENGTH_SHORT);

                        }
                        Thread.sleep(1000);

                    } catch (Exception e) {
                        Toast.makeText(getApplicationContext(), "Erro", Toast.LENGTH_SHORT);
                    }
            }
        }

        TheadInfinity t = new TheadInfinity();
        t.doInBackground();

Both do not lock the application but the screen is blank. So:

inserir a descrição da imagem aqui

I believe the correct mode is not with Thread. There must be some Systems that can be used. However I have not found anywhere "on the internet".

Doubt

How can I do that? =)

  • 4

    Dude, the android has the Broadcasts, which are notifications that the operating system itself for some events. In your case, I believe you should use the Intent filter for the action CONNECTIVITY_CHANGE. In the OR you already have an answer about that. If I’m not mistaken, there were changes in Android 8 and some of these events are no longer available, worth consult.

  • 1

    @Diegorafaelsouza I’ll take a look.. Thank you.

  • 1

    @Diegorafaelsouza took a look. And it looks like that’s it. I’m gonna run some tests tomorrow. Anyway, it would be nice to formulate an answer here about it. Since it could help anyone looking for it. I didn’t even know it existed. =)

  • 1

    It really is a very interesting piece of content. But unfortunately I don’t know [tag:java] or native development [tag:android] to post something really useful without spending more time than I’d like. The tip is for those who have more availability or yourself, if you find your way using this solution =)

  • @Diegorafaelsouza I do not know. kkkk we will leave to the experts then.

2 answers

3


I use this class in my projects:

public class ConexaoInternet extends BroadcastReceiver {

    public enum TipoConexao {TIPO_NAO_CONECTADO,TIPO_WIFI, TIPO_MOBILE};

    private  TipoConexao tipoConexaoATUAL = TipoConexao.TIPO_NAO_CONECTADO; //cache
    private boolean inicializou = false;

    private TipoConexao getStatusConexao(Context context) {
        synchronized (tipoConexaoATUAL){
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            tipoConexaoATUAL = TipoConexao.TIPO_NAO_CONECTADO;

            NetworkInfo activeNetwork = cm==null ? null : cm.getActiveNetworkInfo();
            if (null != activeNetwork) {
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    tipoConexaoATUAL = TipoConexao.TIPO_WIFI;
                }
                if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE){
                    tipoConexaoATUAL = TipoConexao.TIPO_MOBILE;
                }
            }

            return tipoConexaoATUAL;
        }
    }

    public TipoConexao getTipoConexaoAtual(Context context){
        if(!inicializou){
            inicializou = true;
            return getStatusConexao(context);
        }
        return tipoConexaoATUAL;
    }

    public interface IOnMudarEstadoConexao{
        void onMudar(TipoConexao tipoConexao);
    }
    private ArrayList<IOnMudarEstadoConexao> onMudarEstadoConexoesListeners = new ArrayList<>();

    public void addOnMudarEstadoConexao(IOnMudarEstadoConexao t){
        onMudarEstadoConexoesListeners.add(t);
    }
    public void removeOnMudarEstadoConexao(IOnMudarEstadoConexao t){
        onMudarEstadoConexoesListeners.remove(t);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        TipoConexao tipo = getStatusConexao(context);

        for(IOnMudarEstadoConexao o : onMudarEstadoConexoesListeners){
            o.onMudar(tipo);
        }

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            if(connectivityManager!=null){
                for (Network net : connectivityManager.getAllNetworks()) {
                    NetworkInfo networkInfo = connectivityManager.getNetworkInfo(net);
                    if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        connectivityManager.bindProcessToNetwork(net);
                        break;
                    }
                }
            }
        }
    }
}

It is necessary to register when the Activity is created

private ConexaoInternet conexaoInternet;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
    intentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
    conexaoInternet = new ConexaoInternet();
    registerReceiver(conexaoInternet,intentFilter);

It is necessary to remove when Activity is destroyed

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

Example: To add a Switch every time the device changes its connection

conexaoInternet.addOnMudarEstadoConexao(
    new ConexaoInternet.IOnMudarEstadoConexao() {
        @Override
        public void onMudar(ConexaoInternet.TipoConexao tipoConexao) {
            if(tipoConexao == ConexaoInternet.TipoConexao.TIPO_MOBILE ||
                            tipoConexao == ConexaoInternet.TipoConexao.TIPO_WIFI){

                //faça algo quando a conexão for alterada para 3g/wifi

            }else if(tipoConexao == ConexaoInternet.TipoConexao.TIPO_NAO_CONECTADO){

               //faça algo quando o dispositivo perder conexão

            }
        }
    }
);
  • Cool! I’ll test your code tomorrow. Thank you!

  • Anything gives a touch

  • So buddy... it doesn’t work.

  • I put a Toast in "//do something when the connection is changed to 3g/wifi" and in "//do something when the device loses connection"

  • And it doesn’t make any mistake.

  • I put the <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> in the manifest

  • It worked! I forgot to put .show() no Toast... kkkkkk thanks!

  • 1

    Glad I could help :)

  • @Andreicoelho It made a difference <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> or not ?

  • @Digaopartner it will check network connection (3G/WIFI) or internet ?

  • @RBZ it checks the type of connection through the constants. But I adapted it to be the same thing. Because in my app it makes no difference. But imagine that there are things that is better to do only through wifi to not consume a lot of user data.

  • @Andreicoelho I was with a problem like this, where I NEEDED to identify independent of the network, if there is an internet connection. If you have this and you can give it to me somehow, I really appreciate it, or even the link. :]

  • @RBZ your case is similar to mine, right?

  • 2

    @RBZ on having to insert <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> did not make a difference. With or without worked. But I will search because it may be that without it, in previous versions may not work.

  • 1

    This line checks the type of internet and if there is a connection. if(tipoConexao == ConexaoInternet.TipoConexao.TIPO_MOBILE ||&#xA; tipoConexao == ConexaoInternet.TipoConexao.TIPO_WIFI){ ...

  • @RBZ I talked to the friend down here (Gaspar). He said you need to put <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> for new activitys. Only main Activity supports this without having to insert this line. I forgot to mention this, but better late than never. Take a look at the conversation. Hug!

  • 1

    @Andreicoelho was worth my dear ! I will look yes ! Thank you for remembering ! ;)

Show 12 more comments

1

First you need to map a action on Androidmanifest.xml:

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

Then it will be possible to create a receiver so that you have an action to do when the connection type changes:

public class ConnectionChanged extends BroadcastReceiver {

    private final String ACTION_CONN_CHANGED = "android.net.conn.CONNECTIVITY_CHANGE";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction() != null && intent.getAction().equals(ACTION_CONN_CHANGED)) {

            //TODO SEU CODIGO
        }
    }
}

And do as @Digaopartnered said, check what type of connection through a modeling and take a second action for each type of connection.

boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

More details in the Android documentation: Determine and monitor connectivity status

  • Thank you. you’ve added a lot.

  • Let me tell you... I tested it without the <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> and it worked. Why it’s important to put this line in the manifest?

  • in fact the <action> informed is an action already existing in the android library, so did not need to declare the action in Mainfest, however if you use a action customized it is necessary to declare it in mainfest before. You could have a <action android:name="MINHA_ACAO" /> and use for the whole project as for example intent.getAction().equals(MINHA_ACAO)

  • Got it. And if there is more than one action I would have to insert in the other actions?

  • 1

    yes, every action customized should be declared in mainfest, if the action is part of the android library, as the android.net.conn.CONNECTIVITY_CHANGE is not necessary, as is the case with this use here

  • Thanks a lot! Thank you!

  • 1

    Thank you warrior! For nothing

Show 2 more comments

Browser other questions tagged

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