Broadcastreceiver для обнаружения сети подключен

Я пытаюсь получить момент, когда пользователь подключается к сети, тогда я подумал, что BroadcastReceiver - хороший подход... Я хотел бы сделать так, чтобы когда пользователь подключается к сети, знал, есть ли у этой сети подключение к Интернет.

Главное также знать, требуется ли Wi-Fi Browse Log in Пример: Handling Network Sign-On документация

Что я пробовал до сих пор?

Я поменял свой BroadcastReceiver на этот

if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
    Log.d("Network", "Internet YAY");
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
    if (isNetworkOnline()) {
        Log.d(TAG, String.valueOf(tikis));
        NetTask TeInternet = new NetTask();
        TeInternet.execute("https://www.google.com");


    }
}

Проблема в том, что когда я пытаюсь подключиться к WiFi без Internet Connection, ввод такой:

D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/Network﹕ Internet YAY
D/RequiresLoginBroadcast﹕ 1 //this occurs sometimes

Я изменил Inner Class на это в соответствии с Handling Network Sign-On документация

doInBackground() метод:

protected Boolean doInBackground(String...params) {
boolean internetAccessExists = false;
String urlToBeAccessed = params[0];
final int TIMEOUT_VALUE_IN_MILLISECONDS = 15000;
URL url;
HttpURLConnection urlConnection = null;
try {
    url = new URL(urlToBeAccessed);
    urlConnection = (HttpURLConnection) url.openConnection();
    //set the respective timeouts for the connection
    urlConnection.setConnectTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
    urlConnection.setReadTimeout(TIMEOUT_VALUE_IN_MILLISECONDS);
    //the redirect check is valid only after the response headers have been received
    //this is triggered by the getInputStream() method
    InputStream in = new BufferedInputStream(urlConnection.getInputStream());
    if (!url.getHost().equals(urlConnection.getURL().getHost())) {
        internetAccessExists = true;
    }
}
//any sort of exception is considered as a redirect.
//more specific exceptions such as SocketTimeOutException and IOException can be handled as well
catch (Exception e) {
    Log.d(TAG, e.toString());
} finally {
    Log.d(TAG, "Finally");
    urlConnection.disconnect();
}
return internetAccessExists;

Что я искал до сих пор?

  1. Как определить, когда WIFI-соединение было установлено в Андроид?
  2. Android WIFI Как определить, когда конкретное соединение WIFI Доступно
  3. BroadcastReceiver не работает (определить, подключен ли Wi-Fi)

И еще ... но, к сожалению, я не нашел правильного ответа для себя.

TL;DR

То, что я пытаюсь сделать, это получить точное событие, когда пользователи подключаются к сети, а затем получить хороший метод, чтобы определить, могу ли я выполнить пинг Google или проверить, есть ли подключение к Интернету (ТОЛЬКО С WIFI, 3G ПОДКЛЮЧЕНИЕ ЗАПРЕЩЕНО), потому что код, который я использую в данный момент, иногда дает сбой...

Я думаю, что это хороший способ узнать, есть ли Internet Connection, поскольку я хочу узнать, требует ли Wi-Fi вход в браузер.

Мы почти закончили... Но я не понимаю, почему я захожу на BroadcastReceiver 4 или даже 5 раз.... и иногда говорю, что есть Internet connection, когда его нет...


person Skizo-ozᴉʞS    schedule 29.07.2015    source источник
comment
проверяет, подключена ли сеть?.....   -  person Skizo-ozᴉʞS    schedule 29.07.2015
comment
Вы можете попробовать пропинговать Google, если это не удастся, нет интернета :)   -  person Sheychan    schedule 29.07.2015
comment
Я думаю, он так хотел (Во-вторых, я хочу, чтобы он звонил только тогда, когда сеть доступна. Если она недоступна, я не хочу получать уведомления....)   -  person BNK    schedule 29.07.2015
comment
Вам нужна возможность подключения wifi или internet?   -  person Darpan    schedule 29.07.2015
comment
@Darpan Я хочу получить момент, когда пользователь подключен к сети, а затем проверить, доступно ли подключение к Интернету, понимаете?   -  person Skizo-ozᴉʞS    schedule 29.07.2015
comment
@Skizo: посмотрю сегодня вечером... пожалуйста, пришли мне напоминание :)   -  person Y.S    schedule 29.07.2015
comment
@Ю.С. Хорошо :) Вы поняли мою проблему? или мне объяснить более подробно? (я отредактировал свой вопрос): P   -  person Skizo-ozᴉʞS    schedule 29.07.2015
comment
Я понял :) ... более подробная информация, безусловно, была бы полезна ...   -  person Y.S    schedule 29.07.2015
comment
Если вам что-то нужно, просто дайте мне знать, я объясню, что вы хотите, если вы что-то не понимаете :) спасибо   -  person Skizo-ozᴉʞS    schedule 29.07.2015
comment
Следуйте stackoverflow.com/questions/15698790/   -  person Ajit Kumar Dubey    schedule 30.07.2015
comment
@ajit Не сработало: С   -  person Skizo-ozᴉʞS    schedule 30.07.2015
comment
@Ю.С. вы проверили?   -  person Skizo-ozᴉʞS    schedule 30.07.2015
comment
@Skizo: извините за задержку, я отправил ответ, дайте мне знать, как дела ... :)   -  person Y.S    schedule 31.07.2015
comment
@Ю.С. Я отредактировал свой вопрос ^^   -  person Skizo-ozᴉʞS    schedule 31.07.2015
comment
@Skizo: извините за задержку ... пожалуйста, потерпите меня, я был очень занят в течение недели, сейчас просматриваю вопрос. Скоро найду решение... :)   -  person Y.S    schedule 01.08.2015
comment
Не могли бы вы отредактировать вопрос и добавить весь свой текущий код?   -  person Y.S    schedule 03.08.2015
comment
@Skizo: извини за задержку, Скизо. Последние несколько недель я был очень занят и, к сожалению, не мог уделить достаточно внимания вашим вопросам. Куда вы дошли с этим? Какой-либо прогресс ? ... :)   -  person Y.S    schedule 07.08.2015
comment
Все еще вхожу в BroadcastReceiver 4 раза ... и иногда это не работает, потому что иногда говорится, что есть подключение к Интернету, когда его нет, поэтому этот метод, чтобы узнать, есть ли подключение к Интернету, я не знаю, хорошо ли это подход..   -  person Skizo-ozᴉʞS    schedule 07.08.2015
comment
Мастер Np делает то, что должен делать, когда у вас есть время, если хотите, помогите мне: P Также вы проверили мои другие вопрос?   -  person Skizo-ozᴉʞS    schedule 07.08.2015


Ответы (6)


Это то, что я сейчас использую, и оно работает отлично. Я получаю уведомление, когда Интернет подключен (а не просто включен, когда есть фактическое подключение к Интернету).
Он также работает для любого типа подключения для передачи данных, но его можно легко изменить, чтобы принимать только Wi-Fi, 3G, 4G. , и т.д.

Код:

public class NetworkReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                Log.d("Network", "Internet YAY");
            } else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
                Log.d("Network", "No internet :(");
            }
        }
    }
}

Манифест:

<receiver
    android:name=".receivers.NetworkReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>
person Moonbloom    schedule 29.07.2015
comment
Итак, ваш код определяет, когда пользователь подключается к определенной сети? - person Skizo-ozᴉʞS; 29.07.2015
comment
Мой код определяет, когда пользователь подключается/отключается от любой сети. - person Moonbloom; 29.07.2015
comment
Тогда Log.d("Network", "No internet :("); означает, что не удалось подключиться к определенной сети? - person Skizo-ozᴉʞS; 29.07.2015
comment
Нет, это означает, что пользователь отключился от Интернета. - person Moonbloom; 29.07.2015
comment
Итак, (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) он не говорит, что когда пользователь подключается к сети, он говорит, что имеет подключение к Интернету? .... это странно - person Skizo-ozᴉʞS; 29.07.2015
comment
Почему внутри интернета YAY, когда я не подключаюсь к ym роутеру и почему в этот интернет YAY входит 4 раза?...... - person Skizo-ozᴉʞS; 07.08.2015
comment
Идентификатор .EXTRA_NETWORK_INFO устарел!! черт - person filthy_wizard; 07.10.2015

public abstract class NetworkReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    if (null != intent) {
        State wifiState = null;  
        State mobileState = null;  
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);  
        wifiState = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();  
        mobileState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();  
        if (wifiState != null && mobileState != null  
                && State.CONNECTED != wifiState  
                && State.CONNECTED == mobileState) {  
            // phone network connect success
            gNetwork();
        } else if (wifiState != null && mobileState != null  
                && State.CONNECTED != wifiState  
                && State.CONNECTED != mobileState) {  
            // no network
            noNetwork();
        } else if (wifiState != null && State.CONNECTED == wifiState) {  
            // wift connect success
            WIFINetwork();
        }
    }
}

}

набор манифеста

 <receiver android:name=".receiver.AssistantReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
person leo    schedule 29.07.2015
comment
Можете ли вы просто объяснить свой код? я не просил 3g - person Skizo-ozᴉʞS; 29.07.2015

Все, что вам нужно, описано в этом документе: Определение и Мониторинг состояния подключения. Также взгляните на этот класс: Connectivity.java.

Вкратце, шаги должны быть следующими:

1. Перехватить трансляцию CONNECTIVITY_CHANGE.

2. В методе onReceive() проверьте наличие подключения к Интернету, а также Wi-Fi или GPRS.

Это должно быть легко реализовать, и оно должно работать без каких-либо проблем. В некоторых случаях, как в случае с HTC и некоторыми устройствами Samsung, поведение может отличаться, если основная ОС была изменена.

person Y.S    schedule 31.07.2015

Я попробовал этот подход (ниже), и он сработал. Еще не полностью протестирован, но я использую аналогичный для получения статуса батареи. Таким образом, меньше кода, и он выполняет свою работу.

private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
                Log.d(LOG_TAG, "We have internet connection. Good to go.");
            } else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
                Log.d(LOG_TAG, "We have lost internet connection");
            }
        }
    }
};

@Override
protected void onResume() {
    super.onResume();
    IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver(networkReceiver, intentFilter);
}

@Override
protected void onPause() {
    super.onPause();
    if (networkReceiver != null)
        unregisterReceiver(networkReceiver);
}
person nmirkov    schedule 29.10.2017

NetworkChangeReceiver.java

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

public class NetworkChangeReceiver extends BroadcastReceiver {

    private NetworkChangeCallback callback;

    public NetworkChangeReceiver(NetworkChangeCallback callback) {
        this.callback = callback;
    }                                               

    @Override
    public void onReceive(Context context, Intent intent) {
        boolean status = isNetworkAvailable(context);
        showLog("" + status);
        if (callback != null) {
            callback.onNetworkChanged(status);
        }
    }

    private boolean isNetworkAvailable(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
            return (activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting());
        } catch (NullPointerException e) {
            showLog(e.getLocalizedMessage());
            return false;
        }
    }

    private void showLog(String message) {
        Log.e("NetworkChangeReceiver", "" + message);
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements NetworkChangeCallback { 

    private NetworkChangeReceiver networkChangeReceiver;

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

        networkChangeReceiver = new NetworkChangeReceiver(this);
    }   

    @Override
    protected void onPause() {
        super.onPause();
        if (networkChangeReceiver != null) {
            unregisterReceiver(networkChangeReceiver);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    public void onNetworkChanged(boolean status) {
        Log.e("MainActivity","Status: " + status);
    }
}

NetworkChangeCallback.java

public interface NetworkChangeCallback {
    void onNetworkChanged(boolean status);
}

AndroidManifest.xml

    <receiver android:name=".NetworkChangeReceiver">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
person Ketan Ramani    schedule 29.01.2020
comment
Это обнаруживается только тогда, когда пользователь переходит из WiFi в сеть передачи данных, верно? Он не проверяет, действительно ли это подключение к Интернету. Я имею в виду, что вы можете подключиться к Wi-Fi, но требуется логин, будет ли он работать, как если бы он был подключен? - person Skizo-ozᴉʞS; 29.01.2020

Я знаю, что это немного поздно, но для будущих читателей новый и предлагаемый метод, кажется, говорит, что вы должны использовать WorkManager. Являясь частью Android X и поддерживаемой до уровня API 14, он упрощает обнаружение и запуск кода при изменении подключения.

val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .build()

val myWorkRequest =
    OneTimeWorkRequestBuilder<MyWorker>()
        .setConstraints(constraints)
        .build()

WorkManager.getInstance(MyApplication.context).enqueue(myWorkRequest)

И класс, который будет выполняться при обнаружении соединения:

class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        doThis()
        return Result.success()
    }

    private fun doThis() {
        Log.d("ASDF", "::onReceive")
    }
}

Дополнительные ресурсы:

person Kenneth Argo    schedule 12.11.2020