Проверьте НАМЕРЕНИЕ подключения к Интернету

Существует ли Android Intent ACTION_XXX, который уведомляет меня о наличии подключения к Интернету?

Я хочу создать экземпляр BroadcastReceiver, который уведомляет мое приложение, когда пользователь включает подключение к Интернету (по Wi-Fi, по GSM и т. д.).

Кто-нибудь может мне помочь?


person CeccoCQ    schedule 22.09.2010    source источник


Ответы (12)


Принятый ответ правильный. Я добавляю только код приемника для завершения:

public class NetworkStateReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
     Log.d("app","Network connectivity change");
     if(intent.getExtras()!=null) {
        NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
            Log.i("app","Network "+ni.getTypeName()+" connected");
        } else if(intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
            Log.d("app","There's no network connectivity");
        }
   }
}
person lujop    schedule 08.01.2012
comment
BroadcastReceiver.onReceive является абстрактным, поэтому вы не можете вызывать super.onReceive(context, intent);. - person Felipe Lima; 11.07.2013
comment
Где вы искали (документацию), чтобы выяснить содержимое пакета getExtras()? - person Ярослав Рахматуллин; 20.01.2014

Обновление ответа @lujop:

public class NetworkStateReceiver extends BroadcastReceiver {
    private static final String TAG = "NetworkStateReceiver";

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

        Log.d(TAG, "Network connectivity change");

        if (intent.getExtras() != null) {
            final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            final NetworkInfo ni = connectivityManager.getActiveNetworkInfo();

            if (ni != null && ni.isConnectedOrConnecting()) {
                Log.i(TAG, "Network " + ni.getTypeName() + " connected");
            } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
                Log.d(TAG, "There's no network connectivity");
            }
        }
    }
}
person Felipe Lima    schedule 10.07.2013
comment
Спасибо за Ваш ответ. Вы решили проблему устаревшего EXTRA_NETWORK_INFO. +1 - person Sami Eltamawy; 02.09.2015
comment
Хотя это, кажется, работает лучше, я никогда не вижу сообщения об отсутствии подключения к сети, несмотря на то, что отключил Wi-Fi и мобильные данные. - person Mr Pablo; 28.09.2015
comment
откуда здесь контекст? - person Bhargav; 03.02.2016
comment
@MrPablo и все, у кого есть такая же проблема, вам нужно зарегистрировать Wi-Fi на приемнике следующим образом: wifi.supplicant.CONNECTION_CHANGE /› ‹action android:name=android.net.wifi.STATE_CHANGE /› ‹action android:name=android.net.conn.CONNECTIVITY_CHANGE /› ‹/intent-filter› ‹/receiver› - person Marc Niceler; 12.05.2017

MyReceiver.java

public class MyReceiver extends BroadcastReceiver{

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

        if(isConnected(context)) Toast.makeText(context, "Connected.", Toast.LENGTH_LONG).show();
        else Toast.makeText(context, "Lost connect.", Toast.LENGTH_LONG).show();
    }

    public boolean isConnected(Context context) {
        ConnectivityManager cm =
                (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null &&
                              activeNetwork.isConnected();
        return isConnected;
    }
}

AndroidManifest.xml

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

ОБНОВЛЕНИЕ

Если ваше приложение нацелено на уровень API 26 или выше, вы не можете использовать манифест для объявления получателя для неявных широковещательных передач (вещательных передач, которые не нацелены конкретно на ваше приложение), за исключением нескольких неявных широковещательных передач, на которые не распространяется это ограничение. В большинстве случаев вместо этого можно использовать запланированные задания.

использование connection = MyReceiver()

// onCreate - onDestroy, onResume - onPause depends on you
override fun onStart() {
    super.onStart()
    registerReceiver(connection, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
  }

override fun onStop() {
    super.onStop()
    // remember unregister to avoid leak
    unregisterReceiver(connection)
  }

ОБНОВЛЕНИЕ 2

CONNECTIVITY_ACTION Эта константа устарела на уровне API 28. Вместо этого приложения должны использовать более универсальные функции requestNetwork(NetworkRequest, PendingIntent), registerNetworkCallback(NetworkRequest, PendingIntent) или registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) для более быстрого и подробного обновления сетевых изменений, которые им важны.

потому что это added in API level 22, поэтому приведенный выше код будет нормально работать на всех версиях Android.

person vuhung3990    schedule 19.05.2014
comment
извините, сэр, вы можете увидеть больше здесь или в Google: stackoverflow .com/questions/14701422/ - person vuhung3990; 03.02.2015
comment
привет, вы можете ответить на это, пожалуйста, stackoverflow.com/questions/28294677 / - person JRE.exe; 03.02.2015
comment
вы можете пропинговать, чтобы проверить доступ в интернет, если тайм-аут подключен, но нет интернета, вы правы, потому что я вижу, что вы уже это сделали - person vuhung3990; 03.02.2015

Отсутствующая часть всех ответов — это напоминание о регистрации для этого действия:

IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(your_receiver, filter);
person hasan    schedule 22.09.2015
comment
Принятый ответ регистрирует слушателя. Это просто делается в XML в манифесте, а не в коде, как вы предлагаете. - person Ridcully; 12.10.2015
comment
@Ridcully Я думаю, что более новые версии SDK (выше 22?) не вызывают приемник автоматически, как раньше. - person Brill Pappin; 17.03.2017
comment
@BrillPappin вы правы - см. комментарий к принятому ответу, который относится к новому разделу в документации Android SDK: developer.android.com/training/monitoring-device-state/ - person Ridcully; 18.03.2017

Я использую трансляцию, чтобы каждый раз проверять соединение. Создайте класс для информации о соединении.

import android.content.Context;
import android.content.ContextWrapper;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;


public class ConnectivityStatus extends ContextWrapper{

    public ConnectivityStatus(Context base) {
        super(base);
    }

    public static boolean isConnected(Context context){

        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo connection = manager.getActiveNetworkInfo();
        if (connection != null && connection.isConnectedOrConnecting()){
            return true;
        }
        return false;
    }
}

Примените код в своей деятельности:

 private BroadcastReceiver receiver = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
        if(!ConnectivityStatus.isConnected(getContext())){
            // no connection
        }else {
            // connected
        }
    }
 };

Зарегистрируйте трансляцию в методе onCreate() вашей активности:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    ..
    ...
    ....
  }

Не забудьте отменить регистрацию/зарегистрироваться в цикле активности:

@Override
protected void onResume() {
    super.onResume();
    your_activity_context.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

}

@Override
protected void onPause() {
    super.onPause();
    your_activity_context.unregisterReceiver(receiver);

}
person W4R10CK    schedule 02.02.2017
comment
Ваше решение - лучшее и самое простое решение, которое я нашел, спасибо :) - person Ahmad Moussa; 22.03.2017
comment
ConnectivityManager.CONNECTIVITY_ACTION больше не рекомендуется. - person tahsinRupam; 24.10.2018

Этот код будет работать (во всех версиях), так как регистрация манифеста не будет работать для устройств 7+(API 25 и выше), см. это ссылка.

private void foo(){
    registerReceiver(connectionBroadcastReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}

private BroadcastReceiver connectionBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null || intent.getExtras() == null)
           return;

        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.getState() == NetworkInfo.State.CONNECTED) {  
            // connected
        } 
    }
};
person Nicky    schedule 17.07.2017
comment
Не могли бы вы объяснить, что такое метод foo() и где/как его использовать? Спасибо. - person Dumbo; 29.01.2018
comment
@EJusius зарегистрируйте получателя в onResume и отмените его регистрацию в onPause - person Santhosh; 02.02.2018
comment
что, если я хочу обнаружить изменение сети, когда приложение/активность не запущено? - person Mohaimanul Chowdhury; 29.08.2018

Продолжение ответа мяу мво

вы можете включить/отключить приемник:

включить

 ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class);
       PackageManager pm = this.getPackageManager();
       pm.setComponentEnabledSetting(receiver,
               PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
               PackageManager.DONT_KILL_APP);
       Toast.makeText(this, "Disabled broadcst receiver", Toast.LENGTH_SHORT).show();
   }

отключить

ComponentName receiver = new ComponentName(MainActivity.this, MyReceiver.class);
       PackageManager pm = this.getPackageManager();
       pm.setComponentEnabledSetting(receiver,
               PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
               PackageManager.DONT_KILL_APP);
       Toast.makeText(this, "Enabled broadcast receiver", Toast.LENGTH_SHORT).show();
   }

где то же самое можно вызвать в намерении или в onCreate

person JRE.exe    schedule 03.02.2015
comment
Опечатки?: Я думаю, вы имеете в виду отключить для включения и наоборот. - person JDOaktown; 16.04.2016

NetworkInfo.isConnected() — ненадежный метод проверки состояния Интернета, он возвращает значение true при наличии сетевого подключения, даже если у него может отсутствовать доступ к Интернету (например, Wi-Fi без Интернета). Более надежным подходом было бы использование ping с CONNECTIVITY_ACTION BroadcastReceiver:

private void registerInternetReceiver()
{
    if (this.internetReceiver != null) return;
    this.internetReceiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive (Context context, Intent intent)
        {
            if (isInternetAvailable()) Log.i ("Tag", "internet status online");
            else Log.i ("Tag", "internet status offline");
        }
    };
    IntentFilter filter = new IntentFilter();
    filter.addAction (ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver (internetReceiver, filter);
}

private boolean isInternetAvailable()
{
    try
    {
        return (Runtime.getRuntime().exec ("ping -c 1 google.com").waitFor() == 0);
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
    return false;
}
person razz    schedule 16.02.2016

Начиная с Android 7++, ответ @fedj не будет работать, но вы можете программно зарегистрировать широковещательный приемник.

Приложения, предназначенные для Android 7.0 (уровень API 24) и выше, не получают широковещательные сообщения CONNECTIVITY_ACTION, если они объявляют получатель широковещательных сообщений в своем манифесте. Приложения по-прежнему будут получать широковещательные сообщения CONNECTIVITY_ACTION, если они зарегистрируют свой BroadcastReceiver с помощью Context.registerReceiver() и этот контекст все еще действителен.

person Zumry Mohamed    schedule 02.05.2018

Я бы прочитал обновленную документацию для нуги + , потому что намерение устарело из-за количества устройств, одной информации о сети недостаточно. Я бы использовал диспетчер подключения (действие подключения, добавить туда переменные) команды и переменные там, потому что большинство из них изменилось только за последний год, и для тестирования, включить данные ячейки всегда активны, подробное ведение журнала и агрессивную передачу, использовать фильтр wlan, если это необходимо :

https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION

person kbrackson    schedule 05.08.2017

** Вы можете поместить эту строку кода во вспомогательные методы и вызывать ее, когда хотите проверить интернет-соединение **

public static class InternetState {
    static ConnectivityManager cm;

    static public boolean isConnected(Context context) {
        try {
            cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        } catch (NullPointerException e) {

        }

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        return isConnected;
    }
}
person PesaCoder    schedule 23.03.2020

person    schedule
comment
Этот код не будет работать на устройстве Android 7+ из-за это - person Shreyash S Sarnayak; 11.03.2017
comment
да, ответ должен быть обновлен для будущих ссылок. - person Sarthak Mittal; 19.04.2017
comment
@ShreyashSSarnayak Это правильно. Я бы добавил, начиная с Android N, вам необходимо зарегистрировать (и отменить регистрацию) ваш широковещательный приемник в действии. Если оставить это в XML-манифесте, это не повлияет на возможность вашей активности получать изменения подключения на Android N. Просто пояснение для тех, кто интересуется. - person severin.julien; 28.05.2017
comment
Приложения, предназначенные для Android 7.0 (уровень API 24) и выше, не получают широковещательные сообщения CONNECTIVITY_ACTION, если они объявляют получатель широковещательных сообщений в своем манифесте. Приложения по-прежнему будут получать широковещательные сообщения CONNECTIVITY_ACTION, если они зарегистрируют свой BroadcastReceiver с помощью Context.registerReceiver() и этот контекст все еще действителен. - person vivek verma; 03.10.2017