149 Stimmen

Wie kann man erkennen, wann eine WIFI-Verbindung in Android hergestellt wurde?

Ich muss erkennen, wann ich eine Netzwerkverbindung über WIFI habe. Welcher Broadcast wird gesendet, um festzustellen, dass eine gültige Netzwerkverbindung hergestellt wurde? Ich muss überprüfen, ob eine gültige Netzwerkverbindung für HTTP besteht. Worauf sollte ich achten und welche zusätzlichen Tests muss ich durchführen, um zu wissen, dass eine gültige Verbindung besteht.

0 Stimmen

Ein Teil dieser Frage wurde bereits hier beantwortet, wie ich fand: stackoverflow.com/questions/4238921/

1 Stimmen

Es stellt sich aber immer noch die Frage, WANN diese Bedingungen überprüft werden sollen.

1 Stimmen

Ich würde gerne wissen, ob es Sendungen gibt, die von einem Rundfunkempfänger aufgefangen werden können?

8voto

amine Punkte 131

Um den WIFI-Verbindungsstatus zu erkennen, habe ich CONNECTIVITY_ACTION aus der ConnectivityManager-Klasse verwendet:

    IntentFilter filter=new IntentFilter();
    filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver(receiver, filter);

und von Ihrem BroadCastReceiver:

    if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
        int networkType = intent.getIntExtra(
                android.net.ConnectivityManager.EXTRA_NETWORK_TYPE, -1);
        if (ConnectivityManager.TYPE_WIFI == networkType) {
            NetworkInfo networkInfo = (NetworkInfo) intent
                    .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (networkInfo != null) {
                if (networkInfo.isConnected()) {

                    // TODO: wifi is connected
                } else {
                    // TODO: wifi is not connected
                }
            }
        }

    }

ps:funktioniert bei mir einwandfrei:)

1 Stimmen

FYI, mit Android 6, wenn Sie eine gültige Zelle Datenverbindung haben, Änderungen in wifi Zustand wird nicht CONNECTIVITY_ACTION auslösen. Der einzige Grund, warum sie es taten, ist, dass der Verbindungsstatus betroffen war, jetzt ist er es nicht.

0 Stimmen

CONNECTIVITY_ACTION: "Diese Konstante wurde in API-Level 28 veraltet. Anwendungen sollten stattdessen die vielseitigeren Funktionen requestNetwork(NetworkRequest, PendingIntent), registerNetworkCallback(NetworkRequest, PendingIntent) oder registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) verwenden, um schnellere und detailliertere Aktualisierungen über die Netzwerkänderungen zu erhalten, die sie interessieren."

6voto

cesargastonec Punkte 404

November 2020:

Ich habe zu viel mit von Google veralteten Elementen gearbeitet. Schließlich fand ich eine Lösung für meine spezielle Anforderung mit "registerNetworkCallback", wie Google derzeit vorschlägt.

Was ich brauchte, war eine einfache Möglichkeit zu erkennen, dass mein Gerät eine IPv4 im WIFI zugewiesen hat. (Ich habe nicht versucht, andere Fälle, meine Anforderung war sehr spezifisch, aber vielleicht diese Methode, ohne veraltete Elemente, wird als Grundlage für andere Fälle dienen).

Getestet mit APIs 23, 24 und 26 (physische Geräte) und APIs 28 und 29 (emulierte Geräte).

    ConnectivityManager cm 
            = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder builder = new NetworkRequest.Builder();

    cm.registerNetworkCallback
            (
                    builder.build(),
                    new ConnectivityManager.NetworkCallback()
                    {
                        @Override
                        public void onAvailable(Network network)
                        {
                            //Actions to take with Wifi available.
                        }
                        @Override
                        public void onLost(Network network)
                        {
                            //Actions to take with lost Wifi.
                        }
                    }

            );

(Implementiert in "MainActivity.Oncreate")

Hinweis: Im Manifest wird "Android.permission.ACCESS_NETWORK_STATE" benötigt.

0 Stimmen

Ich habe die veraltete Version verwendet und einen Mangel festgestellt - ich kann erkennen, ob das WLAN wirklich aus ist, aber nicht, ob das WLAN richtig funktioniert und der Router, an den es angeschlossen ist, nicht. Zeigt der neue Rückruf an, ob Sie tatsächlich mit dem Internet kommunizieren können oder nicht? Oder wird wie bisher nur die SSID angezeigt?

0 Stimmen

@Martin Es tut mir leid. Ich verwende diese Methode nur, um zu erkennen, ob das Gerät eine zugewiesene IPv4 hat (indem ich eine andere Funktion von "onAvailable" aufrufe). Ich prüfe nicht, ob es Internet gibt oder nicht. Internet ist keine spezielle Anforderung in meinem Projekt. Ich bin sicher, dass es andere geeignete Methoden gibt, um den Internetzugang zu überprüfen, die wahrscheinlich auch von "onAvailable" aufgerufen werden können.

0 Stimmen

Beide onLost() y onUnavailable() wird nicht aufgerufen, wenn die App zum ersten Mal gestartet wird und keine Internetverbindung besteht. Haben Sie einen Vorschlag?

5voto

Codegateway Punkte 51

Für diesen Code ist überhaupt keine Genehmigung erforderlich. Er ist nur auf Änderungen des Verbindungsstatus des Wi-Fi-Netzes beschränkt (jedes andere Netz wird nicht berücksichtigt). Der Empfänger wird statisch in der Datei AndroidManifest.xml veröffentlicht und muss nicht exportiert werden, da er vom System aufgerufen wird protected broadcast , NETWORK_STATE_CHANGED_ACTION bei jeder Änderung des Netzverbindungsstatus.

AndroidManifest:

<receiver
    android:name=".WifiReceiver"
    android:enabled="true"
    android:exported="false">

    <intent-filter>
        <!--protected-broadcast: Special broadcast that only the system can send-->
        <!--Corresponds to: android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION-->
        <action android:name="android.net.wifi.STATE_CHANGE" />
    </intent-filter>

</receiver>

BroadcastReceiver-Klasse:

public class WifiReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/*
 Tested (I didn't test with the WPS "Wi-Fi Protected Setup" standard):
 In API15 (ICE_CREAM_SANDWICH) this method is called when the new Wi-Fi network state is:
 DISCONNECTED, OBTAINING_IPADDR, CONNECTED or SCANNING

 In API19 (KITKAT) this method is called when the new Wi-Fi network state is:
 DISCONNECTED (twice), OBTAINING_IPADDR, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK
 or CONNECTED

 (Those states can be obtained as NetworkInfo.DetailedState objects by calling
 the NetworkInfo object method: "networkInfo.getDetailedState()")
*/
    /*
     * NetworkInfo object associated with the Wi-Fi network.
     * It won't be null when "android.net.wifi.STATE_CHANGE" action intent arrives.
     */
    NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

    if (networkInfo != null && networkInfo.isConnected()) {
        // TODO: Place the work here, like retrieving the access point's SSID

        /*
         * WifiInfo object giving information about the access point we are connected to.
         * It shouldn't be null when the new Wi-Fi network state is CONNECTED, but it got
         * null sometimes when connecting to a "virtualized Wi-Fi router" in API15.
         */
        WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
        String ssid = wifiInfo.getSSID();
    }
}
}

Erlaubt:

None

2 Stimmen

Das funktioniert bei Geräten mit < API 26. Wie @Isham vorgeschlagen hat, wird die Aktion in Android O nicht mehr unterstützt

4voto

mbo Punkte 4431

Android O hat die Möglichkeit entfernt, die impliziten Übertragungen für eine WLAN-Statusänderung zu empfangen. Wenn Ihre App also geschlossen ist, können Sie sie nicht mehr empfangen. Die neue WorkManager kann ausgeführt werden, wenn die Anwendung geschlossen ist. Ich habe ein wenig damit experimentiert, und es scheint ganz gut zu funktionieren:

Fügen Sie dies zu Ihren Abhängigkeiten hinzu:

implementation "android.arch.work:work-runtime:1.0.0-alpha08"

WifiConnectWorker.kt

class WifiConnectWorker : Worker() {

    override fun doWork(): Result {
        Log.i(TAG, "I think we connected to a wifi")
        return Result.SUCCESS
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        val workManager = WorkManager.getInstance()

        // Add constraint to start the worker when connecting to WiFi
        val request = OneTimeWorkRequest.Builder(WifiConnectWorker::class.java)
            .setConstraints(Constraints.Builder()
                .setRequiredNetworkType(UNMETERED)
                .build())
            .build()

        // The worker should be started, even if your app is closed
        workManager.beginUniqueWork("watch_wifi", REPLACE, request).enqueue()
    }
}

Denken Sie daran, dass dies nur ein schneller Test für eine einmalige Benachrichtigung war. Es gibt noch mehr zu tun, um immer benachrichtigt zu werden, wenn WiFi ein- und ausgeschaltet ist.

PS: Wenn die App Beenden erzwingen wird der Arbeiter nicht gestartet, es scheint WorkManager storniert dann die Anfragen.

0 Stimmen

Gibt es eine Möglichkeit, Worker zu starten, auch wenn meine App zwangsweise beendet wird. Work Manager arbeitet mit .setRequiredNetworkType(UNMETERED) nur, wenn die App geöffnet ist. Gibt es eine Möglichkeit, den Worker auszulösen, auch wenn die Anwendung beendet ist (erzwungener geschlossener Zustand). Denn implizite Broad Cast Receiver auch etwas eingeschränkt. Was wird die beste Alternative sein?

3voto

Justin Phillips Punkte 1346

Hier ist ein Beispiel für meinen Code, der die Einstellung des Benutzers berücksichtigt, dass er die Kommunikation nur zulässt, wenn er mit Wifi verbunden ist.

Ich rufe diesen Code aus einer IntentService bevor ich versuche, etwas herunterzuladen.

Beachten Sie, dass NetworkInfo wird sein null wenn es keine Netzverbindung gibt.

private boolean canConnect()
{
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

    boolean canConnect = false;
    boolean wifiOnly = SharedPreferencesUtils.wifiOnly();

    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if(networkInfo != null)
    {
        if(networkInfo.isConnected())
        {
            if((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) ||
               (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && !wifiOnly))
            {
                canConnect = true;
            }
        }
    }

    return canConnect;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X