271 votes

Récepteur de diffusion pour vérifier la connexion Internet dans l'application Android

Je développe un récepteur de diffusion Android pour vérifier la connexion Internet.

Le problème est que mon récepteur de diffusion est appelé deux fois. Je veux qu'il soit appelé uniquement lorsque le réseau est disponible. S'il est indisponible, je ne veux pas être notifié.

Voici le récepteur de diffusion

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final ConnectivityManager connMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        final android.net.NetworkInfo wifi = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        final android.net.NetworkInfo mobile = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (wifi.isAvailable() || mobile.isAvailable()) {
            // Faire quelque chose

            Log.d("Réseau disponible", "Drapeau n°1");
        }
    }
}

Voici le manifest.xml

1 votes

0 votes

Il est plus facile d'utiliser github.com/JobGetabu/DroidNet

0 votes

Essayez cette bibliothèque, tout fonctionne si bien. github.com/andrefio/Rx.Network

256voto

Réponse à votre première question : Votre récepteur de diffusion est appelé deux fois parce que

Vous avez ajouté deux

  1. Changement de connexion réseau :

  2. Changement d'état du WiFi :

Utilisez simplement un seul :
.

Il répondra à une seule action au lieu de deux. Voir ici pour plus d'informations.

Réponse à votre deuxième question (vous voulez que le récepteur ne soit appelé qu'une seule fois si une connexion Internet est disponible) :

Votre code est parfait ; vous notifiez seulement lorsque Internet est disponible.

MISE À JOUR

Vous pouvez utiliser cette méthode pour vérifier votre connectivité si vous voulez juste vérifier si votre mobile est connecté à Internet ou non.

public boolean isOnline(Context context) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    //should check null because in airplane mode it will be a null
    return (netInfo != null && netInfo.isConnected());
}

90voto

Vaishali Points 359
public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (checkInternet(context)) {
            Toast.makeText(context, "Réseau disponible, effectuer des opérations", Toast.LENGTH_LONG).show();
        }
    }

    boolean checkInternet(Context context) {
        ServiceManager serviceManager = new ServiceManager(context);
        return serviceManager.isNetworkAvailable();
    }
}

ServiceManager.java

public class ServiceManager {

    Context context;

    public ServiceManager(Context base) {
        context = base;
    }

    public boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}

permissions:

3 votes

Pour moi, le problème était que le récepteur est appelé deux fois en cas de changement de réseau.

11 votes

Pourquoi utiliseriez-vous un ContextWrapper? Je veux comprendre

3 votes

Moi aussi j'ai le même problème que @manivannan... le destinataire appelle deux fois lors du changement de réseau... y a-t-il une solution à cela

65voto

Keshav Gera Points 1892

Vérification du statut Internet à chaque fois en utilisant un récepteur de diffusion :

mise en œuvre du statut Internet

Code source complet disponible sur Google Drive.

AndroidManifest.xml

BroadcastReciever

package com.keshav.networkchangereceiverexample.receivers;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import static com.keshav.networkchangereceiverexample.MainActivity.dialog;

public class NetworkChangeReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        try
        {
            if (isOnline(context)) {
                dialog(true);
                Log.e("keshav", "Connecter à Internet en ligne ");
            } else {
                dialog(false);
                Log.e("keshav", "Échec de la connectivité !!! ");
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    private boolean isOnline(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            //doit vérifier la nullité car en mode avion il sera null
            return (netInfo != null && netInfo.isConnected());
        } catch (NullPointerException e) {
            e.printStackTrace();
            return false;
        }
    }
}

MainActivity.java

package com.keshav.networkchangereceiverexample;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver;

public class MainActivity extends AppCompatActivity {

    private BroadcastReceiver mNetworkReceiver;
    static TextView tv_check_connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
        mNetworkReceiver = new NetworkChangeReceiver();
        registerNetworkBroadcastForNougat();

    }

    public static void dialog(boolean value){

        if(value){
            tv_check_connection.setText("Nous sommes de retour !!!");
            tv_check_connection.setBackgroundColor(Color.GREEN);
            tv_check_connection.setTextColor(Color.WHITE);

            Handler handler = new Handler();
            Runnable delayrunnable = new Runnable() {
                @Override
                public void run() {
                    tv_check_connection.setVisibility(View.GONE);
                }
            };
            handler.postDelayed(delayrunnable, 3000);
        }else {
            tv_check_connection.setVisibility(View.VISIBLE);
            tv_check_connection.setText("Impossible de se connecter à Internet");
            tv_check_connection.setBackgroundColor(Color.RED);
            tv_check_connection.setTextColor(Color.WHITE);
        }
    }

    private void registerNetworkBroadcastForNougat() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
    }

    protected void unregisterNetworkChanges() {
        try {
            unregisterReceiver(mNetworkReceiver);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }

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

activity_main.xml

26voto

Aj 27 Points 1774

Utilisez cette méthode pour vérifier l'état du réseau :

private void checkInternetConnection() {

    if (br == null) {

        br = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {

                Bundle extras = intent.getExtras();

                NetworkInfo info = (NetworkInfo) extras
                        .getParcelable("networkInfo");

                State state = info.getState();
                Log.d("TEST Internet", info.toString() + " "
                        + state.toString());

                if (state == State.CONNECTED) {
                      Toast.makeText(getApplicationContext(), "La connexion Internet est activée", Toast.LENGTH_LONG).show();

                } else {
                       Toast.makeText(getApplicationContext(), "La connexion Internet est désactivée", Toast.LENGTH_LONG).show();
                }

            }
        };

        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver((BroadcastReceiver) br, intentFilter);
    }
}

n'oubliez pas de désinscrire le service dans onDestroy.

Santé!!

14voto

Sumit Jain Points 86

Attention: La déclaration d'un broadcastreceiver pour android.net.conn.CONNECTIVITY_CHANGE est obsolète pour les applications ciblant N et plus récentes. En général, les applications ne doivent pas se fier à cette diffusion et doivent plutôt utiliser JobScheduler ou GCMNetworkManager.

Comme CONNECTIVITY_CHANGE est obsolète, nous devrions utiliser une autre façon de faire la même chose

En utilisant NetworkConnectionLiveData, nous pouvons gérer toutes les versions du système d'exploitation jusqu'à présent et également si le SDK cible est inférieur à Build.VERSION_CODES.LOLLIPOP alors seulement nous pouvons utiliser broadcastReceiver

La meilleure partie est que cette classe utilise LiveData donc pas besoin d'enregistrer un récepteur, utilisez LiveData et il gérera tout

class NetworkConnectionLiveData(val context: Context) : LiveData() {

    private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager

    private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback

    override fun onActive() {
        super.onActive()
        updateConnection()
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback())
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
            else -> {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
                }
            }
        }
    }

    override fun onInactive() {
        super.onInactive()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
        } else {
            context.unregisterReceiver(networkReceiver)
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private fun lollipopNetworkAvailableRequest() {
        val builder = NetworkRequest.Builder()
                .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
        connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback())
    }

    private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network?) {
                    postValue(true)
                }

                override fun onLost(network: Network?) {
                    postValue(false)
                }
            }
            return connectivityManagerCallback
        } else {
            throw IllegalAccessError("Should not happened")
        }
    }

    private val networkReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            updateConnection()
        }
    }

    private fun updateConnection() {
        val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
        postValue(activeNetwork?.isConnected == true)
    }
} 

Utilisation du LiveData dans n'importe quelle classe:

NetworkConnectionLiveData(context ?: return)
    .observe(viewLifecycleOwner, Observer { isConnected ->
        if (!isConnected) {
            // Internet Non Disponible
            return@Observer
        }
        // Internet Disponible
})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X