Java Android Проверьте подключение к Интернету с помощью NetworkCallBack

Я пытаюсь проверить подключение к Интернету с помощью NetworkCallBack. Однако мой код возвращает странные результаты. Пожалуйста помогите. Любая помощь будет оценена.

CheckNetwork.java

    import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkRequest;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

public class CheckNetwork {

    private Context context;
    
    public CheckNetwork(Context context) {
        this.context = context;
    }
    
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void registerNetworkCallback()
    {
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkRequest.Builder builder = new NetworkRequest.Builder();

            connectivityManager.registerDefaultNetworkCallback( new ConnectivityManager.NetworkCallback(){
                                                                   @Override
                                                                   public void onAvailable(Network network) {
                                                                       Log.d("available", "internet");
                                                                       Variables.isNetworkConnected = true;
                                                                       Log.d("Net_Var_In", String.valueOf(Variables.isNetworkConnected));
                                                                   }
                                                                   @Override
                                                                   public void onLost(Network network) {
                                                                       Log.d("not_av", "internet");
                                                                       Variables.isNetworkConnected = false;
                                                                   }
                                                               }

            );
        }catch (Exception e){
            e.printStackTrace();
            Variables.isNetworkConnected = false;
        }

        Log.d("Net_Var_End", String.valueOf(Variables.isNetworkConnected));

    }
}

MainActivity.java

CheckNetwork checkNetwork = new CheckNetwork(getApplicationContext());
    checkNetwork.registerNetworkCallback();
    Log.d("Net_Var_Main", String.valueOf(Variables.isNetworkConnected));

    if(Variables.isNetworkConnected)
    {
        Log.d("Internet", "available");
    }
    else
    {
        setContentView(R.layout.activity_internet);
        return false;
    }

Логкат:

Когда Интернет подключен/доступен: (даже несмотря на то, что он печатает, что Интернет доступен, он все равно переходит к layout_internet.., который является макетом, когда Интернет НЕ доступен)

    2020-07-17 14:07:09.735 3671-3671/com.example.scrollingtext D/Net_Var_End: false
2020-07-17 14:07:09.735 3671-3671/com.example.scrollingtext D/Net_Var_Main: false
2020-07-17 14:07:09.794 3671-3671/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2020-07-17 14:07:09.795 3671-3671/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2020-07-17 14:07:09.816 3671-3702/com.example.scrollingtext D/available: internet
2020-07-17 14:07:09.816 3671-3702/com.example.scrollingtext D/Net_Var_In: true

Когда Интернет не подключен/не доступен: (даже несмотря на то, что он печатает, что Интернет доступен, он все равно переходит к layout_internet.., который является макетом, когда Интернет НЕ доступен)

    2020-07-17 14:09:31.611 3744-3744/com.example.scrollingtext D/Net_Var_End: false
2020-07-17 14:09:31.611 3744-3744/com.example.scrollingtext D/Net_Var_Main: false
2020-07-17 14:09:31.663 3744-3744/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2020-07-17 14:09:31.663 3744-3744/com.example.scrollingtext W/e.scrollingtex: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2020-07-17 14:09:31.678 3744-3776/com.example.scrollingtext D/available: internet
2020-07-17 14:09:31.678 3744-3776/com.example.scrollingtext D/Net_Var_In: true

ИЗМЕНИТЬ

На основе CheckNetwork.java, который отслеживает состояние сети с помощью NetworkCallBack... как бы вы изменили макет перед экраном пользователя, когда запускаются OnAvailable() и OnLost()? Я хотел бы открыть layout_internet при запуске OnLost()... а затем layout_activity_main при запуске OnAvailable. Это должно происходить изнутри CheckNetwork. Итак, похоже, я ищу доступ к setContentView (который доступен только в MainActivity) из OnAvailable или OnLost. Или есть другой способ открыть layout_internet и layout_activity_main, когда интернет доступен/потерян?


person imim    schedule 17.07.2020    source источник
comment
Вы регистрируете новый NetworkCallback по умолчанию, который срабатывает и выполняет некоторую работу в другом потоке. Тем временем значение isNetworkConnected регистрируется дважды: Net_Var_End и Net_Var_Main. Ваш основной выключается и отображает это для вас. Позже NetworkCallback, наконец, получает вызов onAvailable и изменяет isNetworkConnected на true.   -  person V.C.    schedule 17.07.2020
comment
Спасибо. Но почему он переходит в состояние onAvailable в случае отсутствия подключения к интернету?   -  person imim    schedule 17.07.2020
comment
Вы уверены, что нет доступной сети, а не просто нет доступного Интернета? Локальный Wi-Fi отключен и/или внутреннее сетевое устройство неактивно или отключено DSL-соединение?   -  person V.C.    schedule 17.07.2020
comment
Интернет недоступен. Я вручную отключил WIFI и не имею мобильной сети. Это тот случай, который я тестирую. Извините за дезинформацию.   -  person imim    schedule 17.07.2020
comment
Похоже, что сотовая сеть тоже считается сетью, так что только отключение WiFi не будет считаться на устройстве с симкартой. stackoverflow.com/questions/53863034/ также не забудьте позвонить Суперу при обратном вызове: super.onAvailable(network);   -  person V.C.    schedule 17.07.2020
comment
Хорошо спасибо. Как лучше всего проверить, доступно ли подключение к Интернету, будь то WIFI (подключено или подключено, но нет доступа к Интернету) или мобильная сеть?   -  person imim    schedule 17.07.2020
comment
Эта ссылка показывает, как сделать вызывающий абонент, который различает их, а по умолчанию нет. Вы должны установить NetworkCapabilities: val builder = NetworkRequest.Builder() builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) //or NET_CAPABILITY_INTERNET or TRANSPORT_WIFI   -  person V.C.    schedule 17.07.2020
comment
Спасибо, я добавил это, и теперь обратите внимание, что когда WIFI потерян, но Cell доступен, он представит потерянную сеть (из WIFI), а затем найденную сеть (из мобильной сети).   -  person imim    schedule 18.07.2020
comment
Похоже, у вас есть ответ на ваш вопрос. У вас еще нет возможности публиковать ответы? или вам нужно больше репутации? Возможно, вам придется отредактировать свой вопрос, чтобы другие могли извлечь пользу из того, что вы узнали. Кроме того, если вы нашли какие-либо из моих комментариев полезными, не стесняйтесь голосовать за них, чтобы они были более заметны для других.   -  person V.C.    schedule 20.07.2020


Ответы (2)


верный!!

if(Variables.isNetworkConnected)
    {
        Log.d("Internet", "available");
    }
    else
    {
//        -------> load net not available layout here
        setContentView(R.layout.activity_internet);
        return false;
    }
person notTdar    schedule 17.07.2020
comment
Простите мою глупость здесь .. пожалуйста, объясните. Когда нет подключения к Интернету, он возвращается к layout.activity_internet. И даже когда есть подключение к Интернету, он возвращается к тому же макету. Почему? - person imim; 17.07.2020

Вы можете просмотреть этот код: https://github.com/vladan29/internet_monitor Это рабочий код. который постоянно уведомляет подписанные классы об изменениях в сети. Вы можете использовать стандартный приемник Android вместо EventBus, но липкое намерение устарело, и у вас будут проблемы с начальным состоянием. Если вы клонируете это приложение, вы можете следить за состоянием подключения и некоторыми другими значениями на экране телефона.

Я должен добавить некоторые пояснения. Вы не можете просто использовать onLost() для обнаружения отсутствия подключения к Интернету. Это имеет правильную работу, только если у вас есть один интернет в этом районе. Если у вас есть WIFI и CELLULAR, когда один начинает терять сигнал, другой триггер onAvailable(), но onLost() срабатывает позже. В этот момент у вас уже есть живое соединение, и значение isConnected должно быть истинным.

Теперь вы можете использовать библиотеку по ссылке: https://github.com/vladan29/internet_checker/blob/master/README.md#internet_checker

person Vladan Starcevic    schedule 22.07.2020