Odbiornik do sprawdzania połączenia internetowego w aplikacji na Androida


239

Rozwijam odbiornik transmisji dla systemu Android do sprawdzania połączenia internetowego.

Problem polega na tym, że mój odbiornik jest wywoływany dwa razy. Chcę, aby został wywołany tylko wtedy, gdy sieć jest dostępna. Jeśli jest niedostępny, nie chcę otrzymywać powiadomień.

To jest odbiornik transmisji

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final ConnectivityManager connMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        final android.net.NetworkInfo wifi = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        final android.net.NetworkInfo mobile = connMgr
                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (wifi.isAvailable() || mobile.isAvailable()) {
            // Do something

            Log.d("Network Available ", "Flag No 1");
        }
    }
}

To jest plik manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcastreceiverforinternetconnection"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name=".NetworkChangeReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


Łatwiej jest używać github.com/JobGetabu/DroidNet
Job M

Wypróbuj tę bibliotekę, wszystko działa tak płynnie. github.com/andrefio/Rx.Network
Lucky Rana

Odpowiedzi:


239

Odpowiedz na pierwsze pytanie : Twój odbiornik jest wywoływany dwa razy, ponieważ

Dodałeś dwa <intent-filter>

  1. Zmiana połączenia sieciowego:
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

  2. Zmiana stanu WiFi:
    <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />

Wystarczy użyć jednego:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />.

Będzie reagować tylko na jedną akcję zamiast dwóch. Zobacz tutaj, aby uzyskać więcej informacji.

Odpowiedz na drugie pytanie (jeśli chcesz, aby odbiorca zadzwonił tylko raz, jeśli jest dostępne połączenie internetowe):

Twój kod jest idealny; powiadamiasz tylko wtedy, gdy internet jest dostępny.

AKTUALIZACJA

Możesz użyć tej metody do sprawdzenia łączności, jeśli chcesz po prostu sprawdzić, czy telefon komórkowy jest połączony z Internetem, czy nie.

public boolean isOnline(Context context) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    //should check null because in airplane mode it will be null
    return (netInfo != null && netInfo.isConnected());
}

Nie, moje drugie pytanie brzmi: Chcę otrzymywać powiadomienia, gdy tylko sieć jest dostępna, ale jeśli telefon traci sieć, powiadamia mnie o tym.
Nikhil Agrawal

8
to samo tutaj. Właśnie się <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />zarejestrowałem, ale mój odbiornik wciąż dzwoni dwukrotnie. Nie jest to naprawdę duży problem, ale chciałbym wiedzieć, dlaczego.
Yeung

1
Znam to wszystko, ale mam wątpliwości. Zrobiłem kilka testów i odkryłem, że odbiorniki te wykrywają, czy radio Wi-Fi / telefon włącza się, czy wyłącza, lub po prostu, czy twoje urządzenie ma adres IP. Problem pojawia się, gdy na przykład mój telefon jest podłączony do punktu dostępu Wi-Fi, ale taki punkt dostępu nie ma Internetu. Kod / telefon powiedz mi, że jest to połączenie danych, niezależnie od tego, czy punkt dostępu zapewnia mu dostęp do Internetu, czy nie. Czy ktoś wie, jak stworzyć prawdziwy odbiornik danych w Internecie, a nie tylko odbiornik WiFI / On / Off?
Josh

6
@JosueGalindo onReceiving, możesz użyć tego kodu, aby dowiedzieć się, czy urządzenie jest podłączone do Internetu pastebin.com/dV3pJjkm
Seshu Vinay

1
Deklarowanie odbiornika dla android.net.conn.CONNECTIVITY_CHANGE jest nieaktualne w przypadku aplikacji kierowanych na N i wyżej. Zasadniczo aplikacje nie powinny polegać na tej emisji i zamiast tego używać JobScheduler lub GCMNetworkManager. teraz ????
Pratik Butani,

77
public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (checkInternet(context)) {
            Toast.makeText(context, "Network Available Do operations", Toast.LENGTH_LONG).show();
        }
    }

    boolean checkInternet(Context context) {
        ServiceManager serviceManager = new ServiceManager(context);
        if (serviceManager.isNetworkAvailable()) {
            return true;
        } else {
            return false;
        }
    }
}

ServiceManager.java

public class ServiceManager {

    Context context;

    public ServiceManager(Context base) {
        context = base;
    }

    public boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}

uprawnienia:

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

3
dla mnie problem polegał na dwukrotnym wywołaniu odbiornika przy zmianie sieci?
manivannan

9
dlaczego miałbyś używać ContextWrapper? Chcesz zrozumieć
Darpan,

3
dostaję też problem @manivannan ... odbiorca dzwoni dwukrotnie przy zmianie sieci ... czy istnieje na to rozwiązanie
venkat

Nie ma potrzeby rozszerzania ServiceManager o ContextWrapper.
Yogesh Seralia,

Po co to do cholery jest? ServiceManager extends ContextWrapper? Dlaczego musisz rozszerzyć ContextWrapper? CZEMU!?
Neon Warge

56

Sprawdzanie statusu Internetu za każdym razem za pomocą Odbiornika transmisji:

wdrożenie statusu Internetu

Pełny kod źródłowy dostępny na Dysku Google .

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<receiver android:name=".receivers.NetworkChangeReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
</receiver>

BroadcastReciever

package com.keshav.networkchangereceiverexample.receivers;

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

import static com.keshav.networkchangereceiverexample.MainActivity.dialog;

public class NetworkChangeReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        try
        {
            if (isOnline(context)) {
                dialog(true);
                Log.e("keshav", "Online Connect Intenet ");
            } else {
                dialog(false);
                Log.e("keshav", "Conectivity Failure !!! ");
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    private boolean isOnline(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            //should check null because in airplane mode it will be null
            return (netInfo != null && netInfo.isConnected());
        } catch (NullPointerException e) {
            e.printStackTrace();
            return false;
        }
    }
}

MainActivity.java

package com.keshav.networkchangereceiverexample;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;

import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver;

public class MainActivity extends AppCompatActivity {

    private BroadcastReceiver mNetworkReceiver;
    static TextView tv_check_connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
        mNetworkReceiver = new NetworkChangeReceiver();
        registerNetworkBroadcastForNougat();

    }

    public static void dialog(boolean value){

        if(value){
            tv_check_connection.setText("We are back !!!");
            tv_check_connection.setBackgroundColor(Color.GREEN);
            tv_check_connection.setTextColor(Color.WHITE);

            Handler handler = new Handler();
            Runnable delayrunnable = new Runnable() {
                @Override
                public void run() {
                    tv_check_connection.setVisibility(View.GONE);
                }
            };
            handler.postDelayed(delayrunnable, 3000);
        }else {
            tv_check_connection.setVisibility(View.VISIBLE);
            tv_check_connection.setText("Could not Connect to internet");
            tv_check_connection.setBackgroundColor(Color.RED);
            tv_check_connection.setTextColor(Color.WHITE);
        }
    }


    private void registerNetworkBroadcastForNougat() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
    }

    protected void unregisterNetworkChanges() {
        try {
            unregisterReceiver(mNetworkReceiver);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterNetworkChanges();
    }
}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.keshav.networkchangereceiverexample.MainActivity">

    <TextView
        android:id="@+id/tv_check_connection"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Connection establised !"
        android:padding="25dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:gravity="center"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

Jest bardzo przydatny tak samo jak YouTube za każdym razem, gdy sprawdzasz online, offline
Keshav Gera

Dzięki za świetny post. Dlaczego dodałeś to: Build.VERSION.SDK_INT> = Build.VERSION_CODES.M) w registerNetworkBroadcastForNougat? Manifest nie działa w Androidzie N i Up, a M powinno być w porządku
Amir

4
zduplikowany kod w registerNetworkBroadcastForNougat ()
lenhuy2106

nie powinno być innego w tym segmencie kodu? 'if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.N) {registerReceiver (mNetworkReceiver, nowy IntentFilter (ConnectivityManager.CONNECTIVITY_ACTION)); } else if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.M) {registerReceiver (mNetworkReceiver, nowy IntentFilter (ConnectivityManager.CONNECTIVITY_ACTION)); } '
Siddharth

Oczekiwane zachowanie. Dzięki!
Simão Garcia

26

Użyj tej metody, aby sprawdzić stan sieci:

private void checkInternetConnection() {

    if (br == null) {

        br = new BroadcastReceiver() {

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

                Bundle extras = intent.getExtras();

                NetworkInfo info = (NetworkInfo) extras
                        .getParcelable("networkInfo");

                State state = info.getState();
                Log.d("TEST Internet", info.toString() + " "
                        + state.toString());

                if (state == State.CONNECTED) {
                      Toast.makeText(getApplicationContext(), "Internet connection is on", Toast.LENGTH_LONG).show();

                } else {
                       Toast.makeText(getApplicationContext(), "Internet connection is Off", Toast.LENGTH_LONG).show();
                }

            }
        };

        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver((BroadcastReceiver) br, intentFilter);
    }
}

pamiętaj, aby wyrejestrować usługę w usłudze onDestroy.

Twoje zdrowie!!


9
public static boolean isNetworkAvailable(Context context) {
        boolean isMobile = false, isWifi = false;

        NetworkInfo[] infoAvailableNetworks = getConnectivityManagerInstance(
                context).getAllNetworkInfo();

        if (infoAvailableNetworks != null) {
            for (NetworkInfo network : infoAvailableNetworks) {

                if (network.getType() == ConnectivityManager.TYPE_WIFI) {
                    if (network.isConnected() && network.isAvailable())
                        isWifi = true;
                }
                if (network.getType() == ConnectivityManager.TYPE_MOBILE) {
                    if (network.isConnected() && network.isAvailable())
                        isMobile = true;
                }
            }
        }

        return isMobile || isWifi;
    }

/* You can write such method somewhere in utility class and call it NetworkChangeReceiver like below */
public class NetworkChangedReceiver extends BroadcastReceiver 
{
@Override
    public void onReceive(Context context, Intent intent) {

        if (isNetworkAvailable(context)) 
                {
             Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); 


    }
    }
}

Powyższy odbiornik zostanie wywołany tylko wtedy, gdy stan sieci zmieni się na podłączony, a nie po rozłączeniu.


7

Wiem, że ten wątek jest stary i zawiera pełną odpowiedź, ale uważam, że następujące osoby mogą pomóc niektórym ludziom.

Kod w treści pytania zawiera błąd, którego nikt tutaj nie rozwiązał. @Nikhil sprawdza, czy wifi / telefon komórkowy jest dostępny, a nie, jeśli jest podłączony.

Poprawka jest tutaj:

@Override
public void onReceive(final Context context, final Intent intent) {
    final ConnectivityManager connMgr = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    final android.net.NetworkInfo wifi = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    final android.net.NetworkInfo mobile = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    if (wifi.isConnected() || mobile.isConnected()) {
      // do stuff
    }
}

Tak, chcę tylko zasugerować to samo, poprawka wifi.isConnected ()
Erich García

7

oczywisty:

<receiver android:name=".your.namepackage.here.ConnectivityReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
    </intent-filter>
</receiver>

klasa dla odbiorcy:

public class ConnectivityReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        switch (action) {
            case ConnectivityManager.CONNECTIVITY_ACTION:
                DebugUtils.logDebug("BROADCAST", "network change");
                if(NetworkUtils.isConnect()){
                    //do action here
                }
            break;
        }
    }
}

i narzędzia takie jak przykład:

public class NetworkUtils {

    public static boolean isConnect() {
        ConnectivityManager connectivityManager = (ConnectivityManager) Application.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Network[] netArray = connectivityManager.getAllNetworks();
            NetworkInfo netInfo;
            for (Network net : netArray) {
                netInfo = connectivityManager.getNetworkInfo(net);
                if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
                    //if (netInfo.getState().equals(NetworkInfo.State.CONNECTED)) {
                    Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
                    return true;
                }
            }
        } else {
            if (connectivityManager != null) {
                @SuppressWarnings("deprecation")
                NetworkInfo[] netInfoArray = connectivityManager.getAllNetworkInfo();
                if (netInfoArray != null) {
                    for (NetworkInfo netInfo : netInfoArray) {
                        if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
                            //if (netInfo.getState() == NetworkInfo.State.CONNECTED) {
                            Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
}

7

tylko dla kogoś, kto chce dynamicznie zarejestrować transmisję:

BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (checkWifiConnect()) {
            Log.d(TAG, "wifi has connected");
            // TODO
        }
    }
};

private void registerWifiReceiver() {
    IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    mContext.registerReceiver(mWifiReceiver, filter);
}

private void unregisterWifiReceiver() {
    mContext.unregisterReceiver(mWifiReceiver);
}

private boolean checkWifiConnect() {
    ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    if (networkInfo != null
            && networkInfo.getType() == ConnectivityManager.TYPE_WIFI
            && networkInfo.isConnected()) {
        return true;
    }
    return false;
}

7

Spróbuj tego

public class ConnectionBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {


    if (<Check internet connection available >) { 
        Toast.makeText(context, "connect to the internet", Toast.LENGTH_LONG).show();

        /*upload background upload service*/
        Intent serviceIntent = new Intent(context,<your service class>);
        context.startService(serviceIntent);


    }else{
        Toast.makeText(context, "Connection failed", Toast.LENGTH_LONG).show();

    }
    }
}

Gdy tylko połączenie z Internetem zostanie wyzwolone, ten (BroadcastReciever) zostanie załadowany


Jak zarejestrować ten odbiornik? Jaki filtr zamiarów?
Stealth Rabbi

6

Dokumenty CONNECTIVITY_ACTION :

Aplikacje kierowane na system Android 7.0 (poziom API 24) i wyższy nie otrzymają tej transmisji, jeśli zadeklarują odbiornik transmisji w swoim manifeście. Aplikacje nadal będą odbierać transmisje, jeśli zarejestrują swój BroadcastReceiver w Context.registerReceiver () i ten kontekst jest nadal aktualny.


5

Oto wygodny sposób na zrobienie tego dla aktywności, fragmentu lub kontekstu. Wyrejestruje się również automatycznie, jeśli zrobisz to dla aktywności / fragmentu (w onDestroy), jeśli chcesz:

abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {
    companion object {
        @JvmStatic
        fun registerWithoutAutoUnregister(context: Context, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
            context.registerReceiver(connectionBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
        }

        @JvmStatic
        fun registerToFragmentAndAutoUnregister(context: Context, fragment: Fragment, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
            val applicationContext = context.applicationContext
            registerWithoutAutoUnregister(applicationContext, connectionBroadcastReceiver)
            fragment.lifecycle.addObserver(object : LifecycleObserver {
                @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                fun onDestroy() {
                    applicationContext.unregisterReceiver(connectionBroadcastReceiver)
                }
            })
        }

        @JvmStatic
        fun registerToActivityAndAutoUnregister(activity: AppCompatActivity, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
            registerWithoutAutoUnregister(activity, connectionBroadcastReceiver)
            activity.lifecycle.addObserver(object : LifecycleObserver {
                @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                fun onDestroy() {
                    activity.unregisterReceiver(connectionBroadcastReceiver)
                }
            })
        }

        @JvmStatic
        fun hasInternetConnection(context: Context): Boolean {
            val info = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
            return !(info == null || !info.isConnectedOrConnecting)
        }
    }

    override fun onReceive(context: Context, intent: Intent) {
        val hasConnection = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)
//        Log.d("AppLog", "conenctivity changed. hasConnection? $hasConnection")
        onConnectionChanged(hasConnection)
    }

    abstract fun onConnectionChanged(hasConnection: Boolean)
}

Zastosowanie we fragmencie:

    ConnectionBroadcastReceiver.registerToFragmentAndAutoUnregister(activity!!, this, object : ConnectionBroadcastReceiver() {
        override fun onConnectionChanged(hasConnection: Boolean) {
            // Log.d("AppLog", "onConnectionChanged:" + hasConnection)
        }
    })

4

Ostrzeżenie: Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.

Ponieważ CONNECTIVITY_CHANGEjest to przestarzałe, powinniśmy użyć innego sposobu robienia tych samych rzeczy

Poniższe NetworkConnectionLiveDataobsłuży całą wersję systemu operacyjnego do tej pory, a także jeśli docelowy zestaw SDK jest mniejszy niż Build.VERSION_CODES.LOLLIPOPtylko wtedy możemy użyćbroadcastReceiver

Najlepsze jest to, że ta klasa używa, LiveDatawięc nie trzeba rejestrować żadnego użycia odbiornika LiveDatai będzie on obsługiwał wszystkie rzeczy

class NetworkConnectionLiveData(val context: Context) : LiveData<Boolean>() {

    private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager

    private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback

    override fun onActive() {
        super.onActive()
        updateConnection()
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback())
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
            else -> {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
                }
            }
        }
    }

    override fun onInactive() {
        super.onInactive()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
        } else {
            context.unregisterReceiver(networkReceiver)
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private fun lollipopNetworkAvailableRequest() {
        val builder = NetworkRequest.Builder()
                .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
        connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback())
    }

    private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network?) {
                    postValue(true)
                }

                override fun onLost(network: Network?) {
                    postValue(false)
                }
            }
            return connectivityManagerCallback
        } else {
            throw IllegalAccessError("Should not happened")
        }
    }

    private val networkReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            updateConnection()
        }
    }

    private fun updateConnection() {
        val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
        postValue(activeNetwork?.isConnected == true)
    }
} 

Wykorzystanie LiveData do dowolnej klasy:

NetworkConnectionLiveData(context ?: return)
    .observe(viewLifecycleOwner, Observer { isConnected ->
        if (!isConnected) {
            // Internet Not Available
            return@Observer
        }
        // Internet Available
})

3
public class AsyncCheckInternet extends AsyncTask<String, Void, Boolean> {

public static final int TIME_OUT = 10 * 1000;

private OnCallBack listener;

public interface OnCallBack {

    public void onBack(Boolean value);
}

public AsyncCheckInternet(OnCallBack listener) {
    this.listener = listener;
}

@Override
protected void onPreExecute() {
}

@Override
protected Boolean doInBackground(String... params) {

    ConnectivityManager connectivityManager = (ConnectivityManager) General.context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

    if ((networkInfo != null && networkInfo.isConnected())
            && ((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || (networkInfo
                    .getType() == ConnectivityManager.TYPE_MOBILE))) {
        HttpURLConnection urlc;
        try {
            urlc = (HttpURLConnection) (new URL("http://www.google.com")
                    .openConnection());
            urlc.setConnectTimeout(TIME_OUT);
            urlc.connect();
            if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) {
                return true;
            } else {
                return false;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return false;

        } catch (IOException e) {
            e.printStackTrace();
            return false;

        }
    } else {
        return false;
    }
}

@Override
protected void onPostExecute(Boolean result) {
    if (listener != null) {
        listener.onBack(result);
    }
}

}


AsynTasks powinien być używany do czegoś naprawdę małego. Zamiast tego powinieneś skorzystać z usługi.
TheLibrarian

3

Dodaj odbiornik rozgłoszeniowy, który może nasłuchiwać zmiany połączenia sieciowego. Następnie sprawdź, czy urządzenie jest podłączone do Internetu lub nie korzysta z ConnectivityManager. Szczegółowe informacje można znaleźć w tym poście lub filmie . Poniżej znajduje się kod:

public class NetworkStateChangeReceiver extends BroadcastReceiver {
  public static final String NETWORK_AVAILABLE_ACTION = "com.ajit.singh.NetworkAvailable";
  public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable";

  @Override
  public void onReceive(Context context, Intent intent) {
    Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION);
    networkStateIntent.putExtra(IS_NETWORK_AVAILABLE,  isConnectedToInternet(context));
    LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent);
  }

  private boolean isConnectedToInternet(Context context) {
    try {
      if (context != null) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
      }
      return false;
    } catch (Exception e) {
      Log.e(NetworkStateChangeReceiver.class.getName(), e.getMessage());
      return false;
    }
  }
}

Napisałem ten odbiornik, aby wyświetlał powiadomienie na ekranie, dlatego widzisz lokalną transmisję ze statusem sieci. Oto kod pokazujący powiadomienie.

public class MainActivity extends AppCompatActivity {

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

    IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION);
    LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
        String networkStatus = isNetworkAvailable ? "connected" : "disconnected";

        Snackbar.make(findViewById(R.id.activity_main), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show();
      }
    }, intentFilter);
  }
}

Aktywność nasłuchuje zamiarów nadawanych przez odbiornik sieciowy i wyświetla powiadomienie na ekranie.


2

Pełna odpowiedź tutaj

Plik menifestu

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

<receiver android:name=".NetworkStateReceiver">
    <intent-filter>
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
  </receiver>

Klasa BroadecardReceiver

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

Rejestrowanie odbiornika w MainActivity

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

Cieszyć się!


1

Nadaj kod odbiorcy, aby sprawdzić zmianę połączenia internetowego:

public class BroadCastDetecter extends BroadcastReceiver {
    public static boolean internet_status = false;
    public static void checkInternetConenction(Context context) {
        internet_status = false;
        ConnectivityManager check = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (check != null) {
            NetworkInfo[] info = check.getAllNetworkInfo();
            if (info != null)
                for (int i = 0; i < info.length; i++)
                {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        internet_status = true;
                    }
                }
            if(internet_status)
            {
               //do what you want to if internet connection is available
            }
        }
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        try {
            checkInternetConenction(context);
        }catch(Exception e){

        }
    }
}

dodaj to do pliku manifestu:

 <receiver android:name=".BroadCastDetecter">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>

1

To sprawdza tylko, czy interfejs sieciowy jest dostępny, nie gwarantuje, że dana usługa sieciowa jest dostępna, na przykład może wystąpić niski sygnał lub przestój serwera

  private boolean isNetworkInterfaceAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    }

jeśli chcesz nawiązać prawdziwe połączenie, aby upewnić się, że Twoje połączenie może gromadzić dane z serwera lub dowolnego adresu URL:

  private boolean isAbleToConnect(String url, int timeout) {
        try {
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            connection.setConnectTimeout(timeout);
            connection.connect();
            return true;
        } catch (Exception e) {
            Log.i("exception", "" + e.getMessage());
            return false;
        }
    }

Ta funkcja musi być owinięta w wątek tła:

final String action = intent.getAction();
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            checkConnectivity(context);
        }
    }


    private void checkConnectivity(final Context context) {
        if (!isNetworkInterfaceAvailable(context)) {
            Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
            return;
        }

        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                final boolean isConnected = isAbleToConnect("http://www.google.com", 1000);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (isConnected)
                            Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show();
                        else
                            Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
                    }
                });

            }
        }).start();

    }

Dodaj wymagane uprawnienia:

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

Dodaj ten wiersz w aplikacji w pliku manifestu:

android:usesCleartextTraffic="true"

Dodaj odbiorcę do pliku manifestu:

<receiver android:name=".ConnectivityChangeReceiver" >
            <intent-filter>

                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>    

Zarejestruj / Wyrejestruj BR w tobie Aktywność:

@Override
    protected void onStart() {
        super.onStart();
        IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(connectivityChangeReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(connectivityChangeReceiver);
    }

to jest cała klasa Broadcast:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

import java.net.URL;
import java.net.URLConnection;

public class ConnectivityChangeReceiver extends BroadcastReceiver {


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

        final String action = intent.getAction();
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            checkConnectivity(context);
        }
    }


    private void checkConnectivity(final Context context) {
        if (!isNetworkInterfaceAvailable(context)) {
            Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
            return;
        }

        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                final boolean isConnected = isAbleToConnect("http://www.google.com", 1000);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (isConnected)
                            Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show();
                        else
                            Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
                    }
                });

            }
        }).start();

    }

    //This only checks if the network interface is available, doesn't guarantee a particular network service is available, for example, there could be low signal or server downtime
    private boolean isNetworkInterfaceAvailable(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    }

    //This makes a real connection to an url and checks if you can connect to this url, this needs to be wrapped in a background thread
    private boolean isAbleToConnect(String url, int timeout) {
        try {
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            connection.setConnectTimeout(timeout);
            connection.connect();
            return true;
        } catch (Exception e) {
            Log.i("exception", "" + e.getMessage());
            return false;
        }
    }
} 

0

Łatwiej jest korzystać z https://github.com/JobGetabu/DroidNet

 @Override
    public void onInternetConnectivityChanged(boolean isConnected) {

        if (isConnected) {
            //do Stuff with internet
            netIsOn();
        } else {
            //no internet
            netIsOff();
        }
    }

    private void netIsOn(){...}

    private void netIsOff(){...}

0

Dodaj uprawnienia:

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

Utwórz odbiornik, aby sprawdzić połączenie

public class NetworkChangeReceiver extends BroadcastReceiver {

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

        if(checkInternet(context))
        {
            Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show(); 
        }

    }

    boolean checkInternet(Context context) {
        ServiceManager serviceManager = new ServiceManager(context);
        if (serviceManager.isNetworkAvailable()) {
            return true;
        } else {
            return false;
        }
    }

}

ServiceManager.java

public class ServiceManager {

    Context context;

    public ServiceManager(Context base) {
        context = base;
    }

    public boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}

0

1) W oczywisty sposób: - zadzwoń do odbiornika jak poniżej

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.safal.checkinternet">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="AllowBackup,GoogleAppIndexingWarning">
        <receiver android:name=".NetworkChangeReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2) Utwórz jedną klasę odbiornika Broad Cast: - W tej klasie dodaj kod kontroli sieci

package com.safal.checkinternet;

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

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        if (isOnline(context)){
            Toast.makeText(context, "Available", Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(context, "Not Available", Toast.LENGTH_SHORT).show();
        }
    }
    public boolean isOnline(Context context) {

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        assert cm != null;
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return (netInfo != null && netInfo.isConnected());
    }    
} 

3) W swoim połączeniu z aktywnym odbiornikiem Broadcast: -

package com.safal.checkinternet;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//Call Broad cast Receiver 
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(new NetworkChangeReceiver(), filter);
    }
}

-1

Przede wszystkim stworzymy klasę, która sprawdzi łączność stanu sieci. Stwórzmy więc klasę:

public class AppStatus {
    private static AppStatus instance = new AppStatus();
    static Context context;
    ConnectivityManager connectivityManager;
    NetworkInfo wifiInfo, mobileInfo;
    boolean connected = false;

    public static AppStatus getInstance(Context ctx) {
        context = ctx.getApplicationContext();
        return instance;
    }

    public boolean isOnline() {
        try {
            connectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            connected = networkInfo != null && networkInfo.isAvailable() &&
                    networkInfo.isConnected();
            return connected;


        } catch (Exception e) {
            System.out.println("CheckConnectivity Exception: " + e.getMessage());
            Log.v("connectivity", e.toString());
        }
        return connected;
    }
}

Teraz stwórz nową klasę odbiorników Broadcast:

public class ConnectivityReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (AppStatus.getInstance(context).isOnline()) {

            Intent intent1=new Intent(context,DisplayAct.class);
            intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent1);




        } else {

            Toast.makeText(context, "Please !! Make your network ON", Toast.LENGTH_SHORT).show();

        }
    }
}

i teraz zarejestruj swój odbiornik na manifeście:

<receiver android:name=".ConnectivityReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
        </receiver>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.