Інструмент ConnectivityManager getNetworkInfo (int) застарілий


144

Використовуючи compileSdkVersion 23 , проте намагаюся підтримати аж 9.

getNetworkInfo(int)було знято в 23. Пропозиція була використана getAllNetworks()і getNetworkInfo(Network)замість цього. Однак для обох потрібен мінімум API 21.

Чи існує клас, який ми можемо використовувати в пакеті підтримки, який може допомогти у цьому?

Я знаю, що рішення було запропоновано раніше , однак виклик моїх мінімальних вимог API 9 становить проблему.


ви можете перевірити версію збірки під час виконання та скористатися відповідним методом
stinepike

1
Чи все-таки це викличе застаріле попередження?
kyleED

Перевірте мій клас ConnectivityObserver, який інкапсулює методи API нижче та вище Android Nougat.
JJD

Відповіді:


166

Ви можете використовувати:

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
}

Або в корпусі вимикача

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 - Так, приймач широкомовної програми в цьому випадку не потрібен. getActiveNetworkInfo () може бути розміщений у своєму власному методі за умови включення посилання на контекст.
Сирний хліб

1
@TheIT - так, док каже: "Ви завжди повинні перевірити isConnected () перед початком мережевого трафіку". Це рішення не ініціює трафік, а лише надає рішення для застарілого виклику getNetworkInfo ().
Сирний хліб

7
Що стосується Android 9, SDK 28, це тепер застаріло.
Zbarcea Christian

32
activeNetwork.getType()застаріло і ConnectivityManager.TYPE_WIFIзастаріло
Годвін

7
Заміна заразcm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
tmm1

63

Що стосується жовтня 2018 року, прийнята відповідь застаріла.

getType()та самі типи тепер застаріли в API рівня 28. З Javadoc:

Абоненти повинні перейти на перевірку NetworkCapability # hasTransport замість однієї з констант NetworkCapability # TRANSPORT *

Для використання NetworkCapabilitiesвам потрібно передати Networkекземпляр getNetworkCapabilities()методу. Щоб отримати цей екземпляр, вам потрібно зателефонуватиgetActiveNetwork() який було додано в API рівня 23.

Тож я вважаю, що зараз правильним способом безпечно перевірити, чи підключений ви до Wi-Fi чи стільникової мережі:

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; 
}

Ви також можете перевірити інші типи TRANSPORT, які ви можете знайти тут .

Важлива примітка: якщо ви підключені до Wi-Fi та до VPN, то ваш поточний стан може бути TRANSPORT_VPNтаким, тому ви можете також перевірити його.

Не забудьте додати наступний дозвіл у файл AndroidManifest:

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

Чи маєTransport (NetworkCapa sposobnosti.TRANSPORT_WIFI) еквівалентний ni.isConnected () && (ni.getType () == ConnnectivityManager.TYPE_WIFI)? Я маю на увазі, чи функція hasTransport () також перевіряє, чи пристрій підключено чи намагається підключитися?
Бісквіт

Знову NetworkInfoамортизується, ви більше не можете користуватися NetWorkInfo, тож як це дає альтернативу?
Прескотт Шартьє

@PrescottChartier цей фрагмент коду має доступ лише до NetworkInfo на SDK <23 пристрої
Том

59

Оновлення лютого 2020 року:

Прийнята відповідь знову застаріла 28 (Android P), але метод її заміни працює лише 23 (Android M). Для підтримки старих пристроїв я написав функцію помічника в.

Як використовувати:

int type = getConnectionType(getApplicationContext());

Він повертає та intви можете змінити його enumу своєму коді:

0: Інтернету немає (можливо, в режимі літака або під час підключення до wi-fi).

1: Стільниковий (мобільні дані, 3G / 4G / LTE будь-що).

2: Wi-Fi.

3: VPN

Ви можете скопіювати або Kotlin, або версію Java для допоміжної функції.

Котлін:

@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
}

Java:

@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
Оскільки у вас є 2 можливі результати, краще використовувати булевий, а не повертати ціле число ...
Крістіан

3
@Christian Як пояснено в жовтому розділі, ця допоміжна функція повертає 3 можливих стану: No Internet, Cellularі Wi-Fi. Якщо ви не переймаєтесь типом з'єднання, сміливо змініть код відповідно до вашої програми.
користувач1032613

1
як щодо коментаря до вищевказаного рішення "якщо ви підключені до Wi-Fi та до VPN, то ваш поточний стан може бути TRANSPORT_VPN, тож ви можете також перевірити його".
Девід

1
@Lukas ви повинні бути обережними, якщо ви використовуєте Booleanобгортковий клас, замість booleanякого примітивний. Якщо виписка, вам доведеться додати чек null. Крім того, що, якщо завтра буде введено ще один новий режим транспорту в NetworkCapability ... так що використання цілого числа для розгалуження допоможе, а також ви можете перейти до випадків комутації.
Shadow Droid

3
я втомився від цього постійного циклу
депресії

16

Оновлена ​​відповідь (19: 07: 2018):

Цей метод допоможе вам перевірити, чи доступне підключення до Інтернету.

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;
    }
}

Стара відповідь:

Для найкращої практики використання коду, імпровізуючи відповідь сирного хліба.

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;
}

Код може бути розміщений у класі Util і з його допомогою можна перевірити, чи телефон підключений до Інтернету через Wi-Fi або мобільний Інтернет з будь-якої частини вашої програми.


3
Я б запропонував перенести отримання активної мережі за межі циклу for.
штолик

20
activeNetwork.isConnectedOrConnecting()тепер застаріло
MHSFisher

1
Я змінюю activeNetwork.isConnectedOrConnecting () на activeNetwork.isConnected
Murillo Comino

Зараз NetworkInfo застаріло. Потрібно ще раз оновити!
Скотт Біггс

13

Прийнята відповідь застаріла у версії 28, тому ось рішення, яке я використовую у своєму проекті.

Повертає тип з'єднання. false: відсутність підключення до Інтернету; вірно: мобільні дані || wifi

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 () також застаріло. Ви можете використовувати activeNetwork.isConnected ();
Аман Верма

11

Цю відповідь оновлено станом на березень 2020 року, яка підтримує API.15 через API.29. Ви можете знайти її за початковою відповіддю

Відповідь лютого 2019 року

Щоб перевірити, чи ви в мережі:

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;
}

Щоб отримати тип підключення до Інтернету до / після 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
            }
        }
    }
}

У всіх випадках потрібен дозвіл на доступ до стану мережі

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

Оновити березень 2020 року

Оскільки NetworkInfoце застаріло, і як API 29, відтепер ми маємо використовуватись ConnectivityManager.NetworkCallbackіз зміною стану мережі onAvailable()та onLost()зворотними викликами.

Використання:

  • Ви можете або скористатися цією бібліотекою , або безпосередньо скористатися нижчим класом утиліти, який є частиною цієї бібліотеки.

Особливості

  • Це LifeCycle усвідомлює, намагаючись LifecycleObserverуникнути витоку пам'яті, роблячи чистку onDestroy()методу.
  • Він підтримує від API 15 (сендвіч з морозивом) через API 29 (Android Q)
  • Для API перед API 21 він використовує контекст BoradcastReceiverі NetworkInfoта використовує ConnectivityManager.NetworkCallbackдля API 21 і вище.
  • Коли і WiFi, так і стільникові мережі ввімкнено, слухач підключення не перерветься при відключенні Wi-Fi під час переходу до стільникової мережі.
  • Якщо стільникова мережа увімкнена, слухач підключення не перерветься, коли підключений Wi-Fi та є активною мережею (оскільки це краща мережа).
  • Якщо ви збираєтеся використовувати бібліотеку, не потрібно включати цей дозвіл android.permission.ACCESS_NETWORK_STATE; але ви повинні включити його, якщо ви збираєтесь використовувати клас корисності.

Можливості

  • Отримайте поточний статус підключення (онлайн / офлайн).
  • Безперервна перевірка / прослуховування підключення до Інтернету та запуск зворотного дзвінка, коли пристрій переходить у режим офлайн чи онлайн.
  • Отримайте тип активного підключення до Інтернету (WiFi або стільникового зв'язку).
  • Отримайте тип усіх доступних мереж (WiFi або стільникового зв'язку). >> Підтримується лише в API 21+
  • Отримайте кількість усіх доступних мереж >> Підтримується лише в 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 будь ласка, перевірте оновлену відповідь, сподіваюся, що це може допомогти
Заїн

Якщо користувач одночасно підключений до Wi-Fi і мобільних даних, і втратить з'єднання в одному з них, onLostбуде викликано дзвінок. onLostне означає, що пристрій втратив зв’язок з Інтернетом, але Мережа втратила зв’язок.
Гохан Арік

@Gokhan Arik .. Приємний улов, я працюю над його вирішенням
Заїн

1

@GokhanArik дякую за допомогу. Я щойно оновив свою відповідь і розширив використання API, будь ласка, повідомте мене, якщо ви помітили помилки
Zain

4

Добре перевірити, чи ваша мережа підключена до Інтернету:

@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
}

Ви також можете перевірити NetworkCapabilities.NET_CAPABILITY_VALIDATED.
JJD

3

Версія Котліна:

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

3

Як запропонував сирний хліб , використовуйте getActiveNetworkInfo ()

getActiveNetworkInfo

Додано в рівень 1 API

NetworkInfo getActiveNetworkInfo ()

Повертає інформацію про поточно активну мережу даних за замовчуванням. Підключившись, ця мережа є маршрутом за замовчуванням для вихідних з'єднань. Ви завжди повинні перевірити isConnected () перед початком мережевого трафіку. Це може повернути нуль, коли немає мережі за замовчуванням. Цей метод вимагає, щоб абонент мав дозвіл ACCESS_NETWORK_STATE. Повертає NetworkInfo об'єктом NetworkInfo для поточної мережі за замовчуванням або null, якщо наразі немає мережі за замовчуванням.

Довідка: 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;
}

Тепер зателефонуйте до методу, для безпечного використання спробуйте ловити

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

І не забудьте додати:

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

дякую, що це корисно. коли ми перевіряємо стан мережі, і якщо Wi-Fi і дані вимкнено, тоді програма не працює, але спробуйте вирішити проблему ..
Rucha Bhatt Joshi

Однак це не спрацьовує, якщо я хочу перевірити, чи існує певний тип мережі, перерахуйте всі наявні мережі, тобтоgetNetworkInfo(ConnectivityManager.TYPE_ETHERNET).isAvailable
m0skit0,

3
застаріле getState ()!
Дієго Венансіо

Кілька застарілих інструкцій!
Скотт Біггс

2

Для того, щоб бути в безпечній стороні, я б запропонував також використовувати метод

NetworkInfo.isConnected ()

Весь метод може бути наступним:

/**
 * 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()застаріло і ConnectivityManager.TYPE_WIFI застаріло
Годвін

2

Ось як я перевіряю, чи використовує поточна мережа стільникова чи ні в останніх версіях 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

(Майже) Усі відповіді застаріли в Android P, тому ось C#рішення ( яке легко слідувати розробникам 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);
}   

Ключовим тут є Android.Net.TransportType


Aaaannnndddd все, що в цьому є ВИГОТОВЛЕНО!
Прескотт Шартьє

@PrescottChartier в якій версії?
Мехді Дехгані

2

Можливо, нам доведеться перевіряти підключення до Інтернету не один раз. Тож нам буде легше, якщо ми напишемо блок коду методом розширення Context. Нижче мої допоміжні розширення для Contextта Fragment.

Перевірка підключення до Інтернету

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)
        }
    }
}

Інші розширення

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

перевірити, чи є Інтернет

@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 () не знайдено нижче в android M (API 28). networkInfo.getState () є застарілим вище для android L.

Отже, остаточна відповідь:

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
Ви кажете, що getActiveNetwork () не знайдено в Android нижче M, але ваш код використовує його на Lollipop !?
3c71

2

У багатьох відповідях досі використовується getNetworkType нижче 23, що застаріло; Використовуйте код нижче, щоб перевірити, чи пристрій має підключення до Інтернету.

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;
}

..

І, не забудьте додати цей рядок у Manifest

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

1

Оскільки опубліковані відповіді дозволяють лише запитувати активну мережу, ось як отримати NetworkInfoбудь-яку мережу, не лише активну (наприклад, мережу Wifi) (вибачте, код Котліна вперед)

(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
}

Для цього потрібен API 21 або новішої версії та дозвіл android.permission.ACCESS_NETWORK_STATE


1
в API 28. застарілі currentNetwork.getType () та ConnectivityManager.TYPE_WIFI - застарілі
18:15 в Abushawish

@Abushawish Яке рекомендоване рішення для API 28?
tmm1

Заміна заразcm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
tmm1

1

NetManager , за допомогою якого можна перевірити підключення до Інтернету на Android Kotlin

Якщо ви використовуєте 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) }
    }
}

Якщо ви використовуєте 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

будь ласка, дотримуйтесь цього підручника, він повинен допомогти тим, хто шукає відповіді.

Примітка мережаInfo застаріла, тому замініть це isNetworkReacheable () з відповіддю @vidha нижче, передаючи getApplicationContext () як параметр

  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

Це працює для мене в Котліні. Багато класів API застаріли в класі Network Manager, тому нижче відповідь охоплює всю підтримку 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
}

Ви також додасте нижче

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

0

Наведений нижче код працює на всіх API (Котлін)

Однак getActiveNetworkInfo () застарілий лише в API 29 і працює на всіх API, тому ми можемо використовувати його в усіх Api нижче 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

Щось на зразок цього:

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;
}

І в основному корпусі програми:

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

Це буде працювати і в Android 10. Він повернеться істинним, якщо підключений до Інтернету, ще повернеться помилково

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
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.