flutternetwork / WiFiFlutter

Flutter plugin suite for various WiFi services.
https://wifi.flutternetwork.dev
283 stars 176 forks source link

Mobile Internet doesn't work, after closing the IOT device wifi connection. #385

Open karthiksensesemi opened 4 months ago

karthiksensesemi commented 4 months ago

I'm using this package for auto-connecting to wifi. Then using the tcp sockets i receive the data. Later, the IOT device gets disconnected and mobile gets switched to either mobile data or another wifi.

The internet gets blocked, unless i restart the app. The internet doesn't work after the communication.

GivDavidL commented 1 month ago

I too have this issue, any fix?

E2-Veera commented 1 month ago

I'm also having this issue any help on this? In my case after IOT device stops the WiFi connection my device should automatically switch to previously configured home wifi.

karthikmohan4 commented 1 month ago

You need to set forceWifiUsage(false) after communicating with IOT device.

E2-Veera commented 4 weeks ago

I have handled this feature Natively Please find the source code below with this you can achieve the following (Use method channel to call this native code in flutter)

  1. Connect to WiFi IOT device using ssid and password
  2. Able to communicate to the IOT device using localhost connection
  3. Once the IOT device stops WiFi connection your android mobile will automatically switch to previously configured WiFi connections and also you are able to use the Internet as well within the app

Connection method For Android 10+ devices

public static CompletableFuture<String> connectWifi(MainActivity context, String ssid, String password,boolean useTimeout) {
        CompletableFuture<String> future = new CompletableFuture<>();
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                Log.d(TAG, "Device is above Android 10....");
                WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
                        .setSsid(ssid)
                        .setWpa2Passphrase(password)
                        .build();

                NetworkRequest networkRequest = new NetworkRequest.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .setNetworkSpecifier(wifiNetworkSpecifier)
                        .build();

                ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                ConnectivityManager.NetworkCallback callback =  new ConnectivityManager.NetworkCallback() {

                    // When the IOT device connection is established, the below callback is triggered. And the Mobile Device will be connected to the IOT device.
                    @Override
                    public void onAvailable(Network network) {
                        Log.d(TAG, "Network is available: " + network);
                        //This callback will automatically trigger the WiFi connection Popup
                        // bindProcessToNetwork is used to perform API operations with IOT devices.
                        connectivityManager.bindProcessToNetwork(network);
                        future.complete("connected");
                    }

                    @Override
                    public void onUnavailable() {
                        Log.d(TAG, "Network is unavailable");
                        future.complete("networkUnavailable");
                    }

                    @Override
                    public void onLosing(Network network, int maxMsToLive) {
                        Log.d(TAG, "Network is losing with maxMsToLive: " + maxMsToLive);
                        future.complete("networkLoosing");
                    }

                    // When the IOT device connection is lost, the below callback is triggered. Then the Connectivity Manager is set to null.
                    // So that the WiFi connection can be re-switched to the previously connected WiFi network.
                    @Override
                    public void onLost(Network network) {
                        Log.d(TAG, "Network is lost: " + network);
                        // Setting bindProcessToNetwork null to use the Internet connection After IOT is diconnected.
                        connectivityManager.bindProcessToNetwork(null);
                        // Unregister the callback to enable Network Switching after IOT is diconnected
                        connectivityManager.unregisterNetworkCallback(this);
                        future.complete("networkLost");
                    }
                };

                if (connectivityManager != null) {
                    if(useTimeout) {
                        connectivityManager.requestNetwork(networkRequest,callback,60000);
                    }else{
                        connectivityManager.requestNetwork(networkRequest,callback);
                    }

                } else {
                    Log.d(TAG, "Connectivity Manager is null....");
                    future.complete("notConnected");
                }
            } else {
                Log.d(TAG, "Android level is low so Executing legacy method");
                future.complete(connectToWifiLegacy(context, ssid, password));
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Exception occurred: " + e.getMessage());
            future.completeExceptionally(e);
        }
        return future;
    }

Connection method for Android 10 below devices

 private static String connectToWifiLegacy(MainActivity context, String ssid, String password) {
        try {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            if (wifiManager == null) {
                return "notConnected";
            }
            WifiConfiguration wifiConfig = new WifiConfiguration();
            wifiConfig.SSID = String.format("\"%s\"", ssid);
            wifiConfig.preSharedKey = String.format("\"%s\"", password);

            // Add the network and connect to it
            int netId = wifiManager.addNetwork(wifiConfig);
            if (netId == -1) {
                return "Failed to add network configuration";
            }
            wifiManager.disconnect();
            wifiManager.enableNetwork(netId, true);
            boolean flag = wifiManager.reconnect();
            Log.d(TAG, "Reconnect result: " + flag);
            return "connected";
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Exception occurred: " + e.getMessage());
            return "exception";
        }
    }