ConnectivityManager getNetworkInfo (int) deprecato


144

Usando compileSdkVersion 23 , cercando comunque di supportare fino al 9.

getNetworkInfo(int)è stato deprecato in 23. Il suggerimento era di usare getAllNetworks()e getNetworkInfo(Network)invece. Tuttavia, entrambi richiedono almeno l'API 21.

C'è una classe che possiamo usare nel pacchetto di supporto che può aiutare con questo?

So che prima era stata proposta una soluzione , tuttavia la sfida dei miei requisiti minimi API di 9 pone un problema.


puoi controllare la versione di build in fase di esecuzione e utilizzare il metodo appropriato
stinepike,

1
Questo lancerà ancora un avviso deprecato?
kyleED

Controlla la mia classe ConnectivityObserver che incapsula i metodi API sotto e sopra Android Nougat.
JJD,

Risposte:


166

Puoi usare:

getActiveNetworkInfo ();

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
        // connected to wifi
    } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // connected to mobile data
    }
} else {
    // not connected to the internet
}

O in una custodia

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            // connected to wifi
            break;
        case ConnectivityManager.TYPE_MOBILE:
            // connected to mobile data
            break;
        default:
            break;
    }
} else {
    // not connected to the internet
}

1
@ShirishHerwade - Sì, in questo caso il ricevitore di trasmissione non è necessario. getActiveNetworkInfo () può essere inserito nel proprio metodo purché sia ​​incluso un riferimento al contesto.
Pane al formaggio,

1
@TheIT - Sì, il documento dice "Dovresti sempre controllare isConnected () prima di avviare il traffico di rete". Questa soluzione non sta iniziando il traffico e ha fornito solo una soluzione alla chiamata getNetworkInfo () obsoleta.
Pane al formaggio

7
A partire da Android 9, SDK 28 questo è ora obsoleto.
Zbarcea Christian,

32
activeNetwork.getType()è deprecato e ConnectivityManager.TYPE_WIFIdeprecato
Godwin,

7
La sostituzione è oracm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
tmm1

63

A partire da ottobre 2018, la risposta accettata è obsoleta.

getType()e i tipi stessi sono ora deprecati nel Livello API 28. Da Javadoc:

I chiamanti dovrebbero passare al controllo NetworkCapabilities # hasTransport invece con una delle costanti NetworkCapabilities # TRANSPORT *

Per poter utilizzare NetworkCapabilities, è necessario passare Networkun'istanza al getNetworkCapabilities()metodo. Per ottenere quell'istanza devi chiamare getActiveNetwork()che è stato aggiunto nel Livello API 23.

Quindi per ora credo che il modo giusto per verificare in sicurezza se sei connesso alla rete Wi-Fi o cellulare è:

public static boolean isNetworkConnected() {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
            final NetworkInfo ni = cm.getActiveNetworkInfo();

            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI || ni.getType() == ConnectivityManager.TYPE_MOBILE));
            }
        } else {
            final Network n = cm.getActiveNetwork();

            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } 
    }

    return false; 
}

Puoi anche verificare altri tipi di TRANSPORT, che puoi trovare qui .

Nota importante: se si è connessi al Wi-Fi e a una VPN, il tuo stato attuale potrebbe essere TRANSPORT_VPN, quindi potresti voler verificarlo anche.

Non dimenticare di aggiungere le seguenti autorizzazioni al tuo file AndroidManifest:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

HasTransport (NetworkCapabilities.TRANSPORT_WIFI) corrisponde a ni.isConnected () && (ni.getType () == ConnnectivityManager.TYPE_WIFI)? Voglio dire, la funzione hasTransport () controlla anche se il dispositivo è connesso o sta provando a connettersi?
Biscotto

Ancora una volta, NetworkInfoè ammortizzato, non è più possibile utilizzare NetWorkInfo, quindi come può fornire un'alternativa?
Prescott Chartier,

@PrescottChartier questo frammento di codice accede a NetworkInfo solo su dispositivi SDK <23
Tom

59

Aggiornamento di febbraio 2020:

La risposta accettata viene nuovamente disapprovata 28 (Android P), ma il suo metodo di sostituzione funziona solo su 23 (Android M). Per supportare i dispositivi più vecchi, ho scritto una funzione di supporto in.

Come usare:

int type = getConnectionType(getApplicationContext());

Restituisce un int, puoi cambiarlo enumnel tuo codice:

0: Internet non disponibile (forse in modalità aereo o in fase di connessione a una rete Wi-Fi).

1: cellulare (dati mobili, 3G / 4G / LTE qualunque).

2: Wi-fi.

3: VPN

È possibile copiare la versione Kotlin o Java della funzione di supporto.

Kotlin:

@IntRange(from = 0, to = 3)
fun getConnectionType(context: Context): Int {
    var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm?.run {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                if (hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_VPN)){
                    result = 3
                }
            }
        }
    } else {
        cm?.run {
            cm.activeNetworkInfo?.run {
                if (type == ConnectivityManager.TYPE_WIFI) {
                    result = 2
                } else if (type == ConnectivityManager.TYPE_MOBILE) {
                    result = 1
                } else if(type == ConnectivityManager.TYPE_VPN) {
                    result = 3
                }
            }
        }
    }
    return result
}

Giava:

@IntRange(from = 0, to = 3)
public static int getConnectionType(Context context) {
    int result = 0; // Returns connection type. 0: none; 1: mobile data; 2: wifi
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
                    result = 3;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = 2;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = 1;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_VPN) {
                    result = 3;
                }
            }
        }
    }
    return result;
}

2
Dato che hai 2 risultati possibili, è meglio usare un valore booleano invece di restituire un numero intero ...
Christian

3
@Christian Come spiegato nella sezione gialla, questa funzione di supporto restituisce 3 possibili stati: No Internet, Cellulare Wi-Fi. Se non ti interessa il tipo di connessione, non esitare a modificare il codice per adattarlo alla tua applicazione.
user1032613

1
che dire del commento nella soluzione sopra "se sei connesso a una rete Wi-Fi ea una VPN, il tuo stato attuale potrebbe essere TRANSPORT_VPN, quindi potresti volerne verificare anche".
David,

1
@Lukas devi stare attento se usi la Booleanclasse wrapper invece della booleanquale è primitiva. In if dichiarazione dovrai aggiungere il controllo per null. Inoltre, se domani venisse introdotta un'altra nuova modalità di trasporto in NetworkCapabilities ... quindi l'utilizzo di numeri interi per le ramificazioni ti aiuterà e puoi anche scegliere i casi switch.
Shadow Droid

3
sono stanco di questo costante ciclo di deprezzamento
Segun Wahaab il

16

Risposta aggiornata (19: 07: 2018):

Questo metodo ti aiuterà a verificare se la connessione Internet è disponibile.

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        return (activeNetwork != null && activeNetwork.isConnectedOrConnecting());
    } else {
        return false;
    }
}

Vecchia risposta:

Per la migliore pratica di riutilizzo del codice, improvvisando la risposta Cheese Bread.

public static boolean isNetworkAvailable(Context context) {
    int[] networkTypes = {ConnectivityManager.TYPE_MOBILE,
            ConnectivityManager.TYPE_WIFI};
    try {
        ConnectivityManager connectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        for (int networkType : networkTypes) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null &&
                    activeNetworkInfo.getType() == networkType)
                return true;
        }
    } catch (Exception e) {
        return false;
    }
    return false;
}

Il codice può essere inserito nella classe Util e può essere utilizzato per verificare se il telefono è connesso a Internet tramite Wifi o Internet mobile da qualsiasi parte dell'applicazione.


3
Suggerirei di spostare l'ottenimento della rete attiva al di fuori del ciclo for.
shtolik,

20
activeNetwork.isConnectedOrConnecting()è ora deprecato
MHSFisher il

1
Cambio activeNetwork.isConnectedOrConnecting () in activeNetwork.isConnected
Murillo Comino

NetworkInfo è ora obsoleto. È necessario aggiornare di nuovo!
Scott Biggs,

13

La risposta accettata è obsoleta nella versione 28, quindi ecco la soluzione che sto usando nel mio progetto.

Restituisce il tipo di connessione. false: nessuna connessione a Internet; true: dati mobili || Wi-Fi

public static boolean isNetworkConnected(Context context) { 
    boolean result = false; 
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = true;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = true;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = true;
                }
            }
        }
    }
    return result;
}

2
activeNetwork.getType () è anche deprecato. Puoi usare activeNetwork.isConnected ();
Aman Verma,

11

C'è un aggiornamento a questa risposta a partire da marzo 2020 che supporta API.15 tramite API.29, puoi trovarlo seguendo la risposta originale

Risposta febbraio 2019

Per verificare se sei online:

boolean isOnline() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
    }
    return activeNetwork != null;
}

Per ottenere il tipo di connettività Internet prima / dopo Android M

void internetType() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities nc = connectivityMgr.getNetworkCapabilities(connectivityMgr.getActiveNetwork());
            if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
            } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
            }
        } else {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                // connected to wifi
            } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                // connected to mobile data
            }
        }
    }
}

Tutti i casi richiedono un'autorizzazione per accedere allo stato della rete

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Aggiornamento marzo 2020

Come NetworkInfoè deprecato e a partire da API 29 da ora dobbiamo usare ConnectivityManager.NetworkCallbackcon il suo cambio di stato della rete onAvailable()e onLost()callback.

Uso:

  • È possibile utilizzare questa libreria o utilizzare direttamente la seguente classe di utilità che fa parte di questa libreria.

Caratteristiche

  • È consapevole del ciclo di vita implementando LifecycleObserverper evitare perdite di memoria eseguendo una pulizia del onDestroy()metodo.
  • Supporta da API 15 (Ice Cream Sandwich) a API 29 (Android Q)
  • Per le API precedenti all'API 21, utilizza un contesto BoradcastReceivere NetworkInfo, e utilizza ConnectivityManager.NetworkCallbackper l'API 21 e successive.
  • Quando entrambe le reti WiFi e cellulare sono attive, l'ascoltatore di connettività non si interromperà quando il WiFi viene disconnesso durante la transizione alla rete cellulare.
  • Quando la rete cellulare è attiva, l'ascoltatore di connettività non si interromperà quando il WiFi è connesso e essendo la rete attiva (poiché questa è la rete preferita).
  • Se hai intenzione di utilizzare la libreria, non è necessario includere questa autorizzazione android.permission.ACCESS_NETWORK_STATE; ma devi includerlo se intendi utilizzare la classe di utilità.

funzionalità

  • Ottieni lo stato di connettività corrente (online / offline).
  • Controllo / ascolto continuo della connessione Internet e attivazione di una richiamata quando il dispositivo passa offline o online.
  • Ottieni il tipo di connessione Internet attiva (WiFi o cellulare).
  • Ottieni il tipo di tutte le reti disponibili (WiFi o cellulare). >> Supportato solo su API 21+
  • Ottieni il numero di tutte le reti disponibili >> Supportato solo su API 21+
@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public class ConnectionUtil implements LifecycleObserver {

    private static final String TAG = "LOG_TAG";
    private ConnectivityManager mConnectivityMgr;
    private Context mContext;
    private NetworkStateReceiver mNetworkStateReceiver;

    /*
     * boolean indicates if my device is connected to the internet or not
     * */
    private boolean mIsConnected = false;
    private ConnectionMonitor mConnectionMonitor;


    /**
     * Indicates there is no available network.
     */
    private static final int NO_NETWORK_AVAILABLE = -1;


    /**
     * Indicates this network uses a Cellular transport.
     */
    public static final int TRANSPORT_CELLULAR = 0;


    /**
     * Indicates this network uses a Wi-Fi transport.
     */
    public static final int TRANSPORT_WIFI = 1;


    public interface ConnectionStateListener {
        void onAvailable(boolean isAvailable);
    }


    public ConnectionUtil(Context context) {
        mContext = context;
        mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        ((AppCompatActivity) mContext).getLifecycle().addObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mConnectionMonitor = new ConnectionMonitor();
            NetworkRequest networkRequest = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    .build();
            mConnectivityMgr.registerNetworkCallback(networkRequest, mConnectionMonitor);
        }

    }


    /**
     * Returns true if connected to the internet, and false otherwise
     *
     * <p>
     * NetworkInfo is deprecated in API 29
     * https://developer.android.com/reference/android/net/NetworkInfo
     * <p>
     * getActiveNetworkInfo() is deprecated in API 29
     * https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetworkInfo()
     * <p>
     * getNetworkInfo(int) is deprecated as of API 23
     * https://developer.android.com/reference/android/net/ConnectivityManager#getNetworkInfo(int)
     */
    public boolean isOnline() {

        mIsConnected = false;

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            // Checking internet connectivity
            NetworkInfo activeNetwork = null;
            if (mConnectivityMgr != null) {
                activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
            }
            mIsConnected = activeNetwork != null;

        } else {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)

            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
                        mIsConnected = true;
                }
            }
        }

        return mIsConnected;

    }


    /**
     * Returns
     * <p> <p>
     * <p><p> NO_NETWORK_AVAILABLE >>> when you're offline
     * <p><p> TRANSPORT_CELLULAR >> When Cellular is the active network
     * <p><p> TRANSPORT_WIFI >> When Wi-Fi is the Active network
     * <p>
     */
    public int getActiveNetwork() {

        NetworkInfo activeNetwork = mConnectivityMgr.getActiveNetworkInfo(); // Deprecated in API 29
        if (activeNetwork != null)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                NetworkCapabilities capabilities = mConnectivityMgr.getNetworkCapabilities(mConnectivityMgr.getActiveNetwork());
                if (capabilities != null)
                    if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                        // connected to mobile data
                        return TRANSPORT_CELLULAR;

                    } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                        // connected to wifi
                        return TRANSPORT_WIFI;
                    }

            } else {
                if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // Deprecated in API 28
                    // connected to mobile data
                    return TRANSPORT_CELLULAR;

                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // Deprecated in API 28
                    // connected to wifi
                    return TRANSPORT_WIFI;
                }
            }
        return NO_NETWORK_AVAILABLE;
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public int getAvailableNetworksCount() {

        int count = 0;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            Network[] allNetworks = mConnectivityMgr.getAllNetworks(); // added in API 21 (Lollipop)
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null)
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                            || networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        count++;
            }

        }

        return count;
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public List<Integer> getAvailableNetworks() {

        List<Integer> activeNetworks = new ArrayList<>();

        Network[] allNetworks; // added in API 21 (Lollipop)
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            allNetworks = mConnectivityMgr.getAllNetworks();
            for (Network network : allNetworks) {
                NetworkCapabilities networkCapabilities = mConnectivityMgr.getNetworkCapabilities(network);
                if (networkCapabilities != null) {
                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                        activeNetworks.add(TRANSPORT_WIFI);

                    if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
                        activeNetworks.add(TRANSPORT_CELLULAR);

                }
            }
        }

        return activeNetworks;
    }


    public void onInternetStateListener(ConnectionStateListener listener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            mNetworkStateReceiver = new NetworkStateReceiver(listener);
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            mContext.registerReceiver(mNetworkStateReceiver, intentFilter);

        } else {
            mConnectionMonitor.setOnConnectionStateListener(listener);
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        ((AppCompatActivity) mContext).getLifecycle().removeObserver(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mConnectionMonitor != null)
                mConnectivityMgr.unregisterNetworkCallback(mConnectionMonitor);
        } else {
            if (mNetworkStateReceiver != null)
                mContext.unregisterReceiver(mNetworkStateReceiver);
        }

    }


    public class NetworkStateReceiver extends BroadcastReceiver {

        ConnectionStateListener mListener;

        public NetworkStateReceiver(ConnectionStateListener listener) {
            mListener = listener;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getExtras() != null) {

                NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo(); // deprecated in API 29

                /*
                 * activeNetworkInfo.getState() deprecated in API 28
                 * NetworkInfo.State.CONNECTED deprecated in API 29
                 * */
                if (!mIsConnected && activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
                    Log.d(TAG, "onReceive: " + "Connected To: " + activeNetworkInfo.getTypeName());
                    mIsConnected = true;
                    mListener.onAvailable(true);

                } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                    if (!isOnline()) {
                        mListener.onAvailable(false);
                        mIsConnected = false;
                    }

                }

            }
        }
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public class ConnectionMonitor extends ConnectivityManager.NetworkCallback {

        private ConnectionStateListener mConnectionStateListener;

        void setOnConnectionStateListener(ConnectionStateListener connectionStateListener) {
            mConnectionStateListener = connectionStateListener;
        }

        @Override
        public void onAvailable(@NonNull Network network) {

            if (mIsConnected)
                return;

            Log.d(TAG, "onAvailable: ");

            if (mConnectionStateListener != null) {
                mConnectionStateListener.onAvailable(true);
                mIsConnected = true;
            }

        }

        @Override
        public void onLost(@NonNull Network network) {

            if (getAvailableNetworksCount() == 0) {
                mConnectionStateListener.onAvailable(false);
                mIsConnected = false;
            }

        }

    }

}

@Rasel, per favore, controlla la risposta aggiornata, spero che possa aiutarti
Zain

Se l'utente è connesso a Wifi e dati mobili contemporaneamente e perde la connessione in uno di essi onLostverrà chiamato. onLostnon significa che il dispositivo ha perso la connessione a Internet, ma una rete ha perso la connessione.
Gokhan Arik,

@Gokhan Arik .. Bella cattura Ci sto lavorando per risolverlo
Zain


@GokhanArik grazie per l'aiuto .. Ho appena aggiornato la mia risposta e ampliato l'utilizzo dell'API, per favore fatemi sapere se notate qualche bug
Zain

4

È bene verificare se la rete è connessa a Internet:

@Suppress("DEPRECATION")
fun isNetworkAvailable(context: Context): Boolean {
    try {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT > 22) {
            val an = cm.activeNetwork ?: return false
            val capabilities = cm.getNetworkCapabilities(an) ?: return false
            capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        } else {
            val a = cm.activeNetworkInfo ?: return false
            a.isConnected && (a.type == ConnectivityManager.TYPE_WIFI || a.type == ConnectivityManager.TYPE_MOBILE)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}

Potresti anche voler controllare NetworkCapabilities.NET_CAPABILITY_VALIDATED.
JJD

3

Versione di Kotlin:

fun isInternetOn(context: Context): Boolean {
   val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
   val activeNetwork = cm?.activeNetworkInfo
   return activeNetwork != null && activeNetwork.isConnected
}

3

Come ha suggerito Cheese Bread , utilizzare getActiveNetworkInfo ()

getActiveNetworkInfo

Aggiunto nel livello API 1

NetworkInfo getActiveNetworkInfo ()

Restituisce i dettagli sulla rete di dati predefinita attualmente attiva. Una volta connessa, questa rete è la route predefinita per le connessioni in uscita. Verificare sempre isConnected () prima di avviare il traffico di rete. Ciò può restituire null quando non esiste una rete predefinita. Questo metodo richiede al chiamante di disporre dell'autorizzazione ACCESS_NETWORK_STATE. Restituisce NetworkInfo un oggetto NetworkInfo per la rete predefinita corrente o null se nessuna rete predefinita è attualmente attiva.

Riferimento: Android Studio

 public final boolean isInternetOn() {

    // get Connectivity Manager object to check connection
    ConnectivityManager connec =
            (ConnectivityManager)getSystemService(getBaseContext().CONNECTIVITY_SERVICE);

    // Check for network connections
    if ( connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTED ||
            connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTING ) {

        // if connected with internet

        Toast.makeText(this, connec.getActiveNetworkInfo().getTypeName(), Toast.LENGTH_LONG).show();
        return true;

    } else if (
            connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED ||
                    connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED  ) {

        Toast.makeText(this, " Not Connected ", Toast.LENGTH_LONG).show();
        return false;
    }
    return false;
}

ora chiama il metodo, per un utilizzo sicuro prova a catturare

try {
    if (isInternetOn()) { /* connected actions */ }
    else { /* not connected actions */ }
} catch (Exception e){
  Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

E non dimenticare di aggiungere:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

grazie è utile. quando controlliamo lo stato della rete e se il wifi e i dati sono entrambi disattivati, quell'app si blocca ma prova a risolvere il problema ..
Rucha Bhatt Joshi

Tuttavia, questo non funziona se voglio verificare se è presente un tipo specifico di rete, elencare tutte le reti presenti, ovverogetNetworkInfo(ConnectivityManager.TYPE_ETHERNET).isAvailable
m0skit0

3
getState () deprecato!
Diego Venâncio,

Diverse istruzioni deprecate!
Scott Biggs,

2

Per essere al sicuro, suggerirei di usare anche il metodo

NetworkInfo.isConnected ()

L'intero metodo potrebbe essere il seguente:

/**
 * Checking whether network is connected
 * @param context Context to get {@link ConnectivityManager}
 * @return true if Network is connected, else false
 */
public static boolean isConnected(Context context){
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnected()) {
        int networkType = activeNetwork.getType();
        return networkType == ConnectivityManager.TYPE_WIFI || networkType == ConnectivityManager.TYPE_MOBILE;
    } else {
        return false;
    }
}

9
activeNetwork.getType()è deprecato e ConnectivityManager.TYPE_WIFI deprecato
Godwin,

2

Ecco come controllo se la rete corrente utilizza cellulare o meno sulle ultime versioni di Android:

val isCellular: Boolean get() {
    val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    } else {
        cm.activeNetworkInfo?.type == ConnectivityManager.TYPE_MOBILE
    }
}

2

(Quasi) Tutte le risposte sono deprecate in Android P, quindi ecco la C#soluzione ( che è facile da seguire per gli sviluppatori Java )

public bool IsOnline(Context context)
{
    var cm = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);

    if (cm == null) return false;

    if (Build.VERSION.SdkInt < BuildVersionCodes.M)
    {
        var ni = cm.ActiveNetworkInfo;

        if (ni == null) return false;

        return ni.IsConnected && (ni.Type == ConnectivityType.Wifi || ni.Type == ConnectivityType.Mobile);
    }

    return cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Wifi)
        || cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Cellular);
}   

La chiave qui è Android.Net.TransportType


Aaaannnndddd tutto in questo è deprecato!
Prescott Chartier,

@PrescottChartier in quale versione?
Mehdi Dehghani il

2

Potrebbe essere necessario controllare la connettività Internet più di una volta. Quindi sarà più facile per noi se scriviamo il blocco di codice in un metodo di estensione di Context. Di seguito sono riportate le mie estensioni di supporto per Contexte Fragment.

Verifica della connessione a Internet

fun Context.hasInternet(): Boolean {
    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Build.VERSION.SDK_INT < 23) {
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        activeNetworkInfo != null && activeNetworkInfo.isConnected
    } else {
        val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (nc == null) {
            false
        } else {
            nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                    nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        }
    }
}

Altre estensioni

fun Context.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) {
    if (hasInternet()) {
        trueFunc(true)
    } else if (notifyNoInternet) {
        Toast.makeText(this, "No Internet Connection!", Toast.LENGTH_SHORT).show()
    }
}

fun Context.hasInternet(
    trueFunc: (internet: Boolean) -> Unit,
    falseFunc: (internet: Boolean) -> Unit
) {
    if (hasInternet()) {
        trueFunc(true)
    } else {
        falseFunc(true)
    }
}

fun Fragment.hasInternet(): Boolean = context!!.hasInternet()

fun Fragment.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) =
    context!!.hasInternet(notifyNoInternet, trueFunc)

fun Fragment.hasInternet(
    trueFunc: (internet: Boolean) -> Unit, falseFunc: (internet: Boolean) -> Unit
) = context!!.hasInternet(trueFunc, falseFunc)

2

controlla se Internet è disponibile

@RequiresPermission(allOf = [
    Manifest.permission.ACCESS_NETWORK_STATE, 
    Manifest.permission.INTERNET
])
fun isInternetAvailable(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    val activeNetworkInfo = connectivityManager!!.activeNetworkInfo
    return activeNetworkInfo != null && activeNetworkInfo.isConnected
}

2

connectivityManager.getActiveNetwork () non si trova sotto android M (API 28). networkInfo.getState () è obsoleto sopra Android L.

Quindi, la risposta finale è:

public static boolean isConnectingToInternet(Context mContext) {
    if (mContext == null) return false;

    ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            final Network network = connectivityManager.getActiveNetwork();
            if (network != null) {
                final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                        nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } else {
            NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
            for (NetworkInfo tempNetworkInfo : networkInfos) {
                if (tempNetworkInfo.isConnected()) {
                    return true;
                }
            }
        }
    }
    return false;
}

1
Dici che getActiveNetwork () non si trova in Android sotto M, ma il tuo codice lo usa su Lollipop!?
3c71

2

Molte risposte usano ancora getNetworkType sotto 23 che è deprecato; utilizzare il codice seguente per verificare se il dispositivo dispone di una connessione Internet.

public static boolean isNetworkConnected(Context context) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
        } else {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnected();
        }
    }

    return false;
}

..

E, non dimenticare di aggiungere questa riga in Manifest

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

1

Poiché le risposte pubblicate ti consentono solo di interrogare la rete attiva, ecco come ottenere NetworkInfoqualsiasi rete, non solo quella attiva (ad esempio la rete Wifi) (scusa, codice Kotlin in anticipo)

(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
    allNetworks.find { getNetworkInfo(it).type == ConnectivityManager.TYPE_WIFI }?.let { network -> getNetworkInfo(network) }
//    getNetworkInfo(ConnectivityManager.TYPE_WIFI).isAvailable // This is the deprecated API pre-21
}

Ciò richiede l'API 21 o successiva e l'autorizzazione android.permission.ACCESS_NETWORK_STATE


1
currentNetwork.getType () e ConnectivityManager.TYPE_WIFI sono entrambi deprecati nell'API 28.
Abushawish,

@Abushawish Qual è la soluzione consigliata per API 28?
tmm1,

La sostituzione è oracm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
tmm1

1

NetManager che è possibile utilizzare per controllare la connessione Internet su Android con Kotlin

Se si utilizza minSdkVersion> = 23

class NetManager @Inject constructor(var applicationContext: Context) {
    val isConnectedToInternet: Boolean?
        get() = with(
            applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                    as ConnectivityManager
        ) {
            isConnectedToInternet()
        }
}

fun ConnectivityManager.isConnectedToInternet() = isConnected(getNetworkCapabilities(activeNetwork))

fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
    return when (networkCapabilities) {
        null -> false
        else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
    }
}

Se si utilizza minSdkVersion <23

class NetManager @Inject constructor(var applicationContext: Context) {
    val isConnectedToInternet: Boolean?
        get() = with(
            applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
                    as ConnectivityManager
        ) {
            isConnectedToInternet()
        }
}

fun ConnectivityManager.isConnectedToInternet(): Boolean = if (Build.VERSION.SDK_INT < 23) {
    isConnected(activeNetworkInfo)
} else {
    isConnected(getNetworkCapabilities(activeNetwork))
}


fun isConnected(network: NetworkInfo?): Boolean {
    return when (network) {
        null -> false
        else -> with(network) { isConnected && (type == TYPE_WIFI || type == TYPE_MOBILE) }
    }
}

fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
    return when (networkCapabilities) {
        null -> false
        else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
    }
}

1

https://www.agnosticdev.com/content/how-detect-network-connectivity-android

segui questo tutorial che dovrebbe aiutare chiunque cerchi risposte.

nota networkInfo è stato deprecato quindi sostituirlo è isNetworkReacheable () con la risposta @vidha sotto il passaggio getApplicationContext () come parametro

  public static boolean isNetworkReacheable(Context context) {
    boolean result = false;
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = true;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = true;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = true;
                }
            }
        }
    }
    return result;
}

0
public boolean isConnectedToWifi(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager == null) {
        return false;
    }

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
        Network network = connectivityManager.getActiveNetwork();
        NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
        if (capabilities == null) {
            return false;
        }
        return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
    } else {
        NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        if (networkInfo == null) {
            return false;
        }
        return networkInfo.isConnected();
    }
}

0

Questo funziona per me a Kotlin. Molte API sono deprecate nella classe Network Manager, quindi la risposta che segue copre tutto il supporto API.

fun isNetworkAvailable(context: Context): Boolean {
    var result = false
    (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                result = isCapableNetwork(this,this.activeNetwork)
            } else {
                val networkInfos = this.allNetworks
                for (tempNetworkInfo in networkInfos) {
                    if(isCapableNetwork(this,tempNetworkInfo))
                        result =  true
                }
            }
        }

    return result
}

fun isCapableNetwork(cm: ConnectivityManager,network: Network?): Boolean{
     cm.getNetworkCapabilities(network)?.also {
        if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
            return true
        } else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
            return true
        }
    }
    return false
}

Aggiungerai anche di seguito

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

0

Il codice seguente funziona su tutte le API. (Kotlin)

Tuttavia, getActiveNetworkInfo () è deprecato solo nell'API 29 e funziona su tutte le API, quindi possiamo usarlo in tutte le API inferiori a 29

fun isInternetAvailable(context: Context): Boolean {
            var result = false
            val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val networkCapabilities = connectivityManager.activeNetwork ?: return false
                val actNw =
                    connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
                result = when {
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            } else {
                connectivityManager.run {
                    connectivityManager.activeNetworkInfo?.run {
                        result = when (type) {
                            ConnectivityManager.TYPE_WIFI -> true
                            ConnectivityManager.TYPE_MOBILE -> true
                            ConnectivityManager.TYPE_ETHERNET -> true
                            else -> false
                        }

                    }
                }
            }

            return result
        }

0

Qualcosa come questo:

public boolean hasConnection(final Context context){
    ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNW = cm.getActiveNetworkInfo();
    if (activeNW != null && activeNW.isConnected())
    {
        return true;
    }
    return false;
}

E nel corpo principale del programma:

if(hasConnection(this)) {
    Toast.makeText(this, "Active networks OK ", Toast.LENGTH_LONG).show();
    getAccountData(token, tel);
}
else  Toast.makeText(this, "No active networks... ", Toast.LENGTH_LONG).show();

0

Funzionerà anche su Android 10. Restituirà vero se connesso a Internet altrimenti restituirà falso.

private fun isOnline(): Boolean {
        val connectivityManager =
                getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val capabilities =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            when {
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                    return true
                }
            }
        }
        return false
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.