Android Question Switch WiFi connection

Acuario

Member
Licensed User
Longtime User
I'm trying to find a way to switch WiFi connections programmatically with B4X.
I have an ESP8266 that when newly connected doesn't know how to connect to WiFi so creates an access point (with ssid and password set by my code).
I want to be able to connect to this AP so I can configure the ESP8266 without having to go to the phone settings to change the WiFi connection.
I've tried with the WiFiConnect library but it doesn't seem to work.
Any ideas?
 

Peter Simpson

Expert
Licensed User
Longtime User
Hello @Acuario,
Give this a go.

You need these libraries.
1627318850552.png


B4X:
Sub GetPermission
    'TESTED USING THE MLWIFI WIFI LIBRARY
    'https://www.b4x.com/android/forum/threads/mlwifi-library-updated-to-v4-00.125051/

    RT.CheckAndRequest(RT.PERMISSION_ACCESS_FINE_LOCATION)

    'For B4XPages
     Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)

    'For Activity
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)

    If Result Then
        Log("Permission granted :-)")
        WiFiInfo
    Else
        Log("Permission not granted :-(")
    End If
End Sub

Sub WiFiInfo
    WiFi.debug = True 
    Log($"Connected - ${WiFi.isWifiConnected}"$)
    Log($"Is online - ${WiFi.isOnline}"$)
    Log($"SSID - ${WiFi.WifiSSID}"$)
    Log($"5GHz - ${WiFi.is5GHzBandSupported}"$)
    Log($"Ping returned ${WiFi.isOnlinePing2("google.co.uk")}"$) 'Only for testing

    'NoEventOnSystemScan: Launches events only on requested scans (True) Or on all scans (False), including system background scans.
    'THIS METHOD SHOULD ONLY BE CALLED ONCE!
    Log("SCAN TIME - Scanning..................................") 
    WiFiScan.startScan("WiFi", False)

    Wait For WiFi_ScanDone(Results() As String, Count As Int)
    For i = 0 To Count - 1
        If Not(Results(i).StartsWith(",")) Then
            Log(Results(i).Replace(",", TAB))
        End If
    Next

'    Return 'FOR TESTING
'    CONNECT CURRENT ANDROID DEVICE TO A NEW WIFI/AP
    WiFi.disconnectWifiAP
    WiFi.connectWifiAP(<AP>, WiFi.SECURITY_WPA2PSK, <PASSWORD>, 5000)

    Wait For WiFi_ConnectionResult(success As Boolean)
    Log($"Connected to WiFi = ${success}"$)
    ToastMessageShow($"Connected to WiFi = ${success}"$, False)
End Sub



Enjoy...
 
Upvote 0

Acuario

Member
Licensed User
Longtime User
This works, thanks. But when I change the connection back to the original wifi I lose connectivity from my app - the phone has connectivity. Changing back to the second wifi and connectivity returns.
Any ideas?
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
But when I change the connection back to the original wifi I lose connectivity from my app
Hey what???????????????????????????????????????
Well that's pretty obvious really, you can't connect to more than 1 AP at any one time.

Well I'm guessing with my answer above that it's not possible. Have you tried searching big G for lets say "Android connecting to multiple APS at the same time"...
 
Upvote 0

Acuario

Member
Licensed User
Longtime User
I'm not connecting to multiple AP's. Let me explain the program flow:

1. I have my phone connected to my Wifi
2. I power up a new ESP that has not been connected to my WiFi so starts it's own AP
3. I click a button in my app that switches the WiFi and connects to the ESP AP WiFi
4. I configure the WiFi for the ESP and via http send the data to the ESP which then reboots and connects to my WiFi. The ESP AP has now gone.
5. The phone reconnects to the original WiFi (as the ESP AP is no longer there).
6. I now send a UDP broadcast message to the ESP so it identifies itself and returns me it's IP address
7. I now communicate with the ESP via HTTP with the IP address returned in step 6.

Step 5 is the problem, the rest works fine. Steps 6 and 7 work fine if I close and restart my app so I know these work.
When the phone reconnects to the original WiFi (which it does without problem) connectivity is available from the phone (other apps such as WhatsApp, internet browsing, ping etc) all work fine. But my app doesn't. It throws an error when I try to use HTTP:

ResponseError. Reason: java.net.SocketException: socket failed: ENONET (Machine is not on the network), Response:

If I put my ESP back into AP mode and reconnect to the ESP AP from my phone (via step 3) I can again communicate correctly with the ESP.

I'm also using UDP in my app and the same error occurs with UDP connectivity after step 5 without restarting the app.

If I close and open my app then it can connect again correctly.

It seems that something related to network connectivity is not being released properly.
I'm using the OkHttpUtils2 for the HTTP connectivity and Network for UDP connectivity.

I have my HTTP routines in a class module (shouldn't make a difference) and the HttpJob is local to the sub so shouldn't be holding on to any old configuration:
B4X:
Sub FetchWebsite(url As String, param() As String) As ResumableSub
    Private myJob As HttpJob
    Dim data As String
    
    myJob.Initialize("", Me)
    If param.Length = 1 Then
        myJob.Download(url)
    Else
        myJob.Download2(url, param)
    End If
    Wait For (myJob) JobDone (myJob As HttpJob)
    If myJob.Success Then
        data = myJob.GetString
    Else
        data = myJob.ErrorMessage
    End If
    myJob.Release
    Return data
End Sub

It's called as follows:
B4X:
Wait For (FetchWebsite("http://" & Main.httpServer & "/status",Array As String("") )) complete(data As String)
Main.httpServer is the IP address of the ESP
 
Upvote 0

Acuario

Member
Licensed User
Longtime User
After much testing and trying various different combinations I finally found something that worked.
After disconnecting I tried 2 scans (with a single scan it failed as above). With 2 scans it worked.
I then tried removing the second scan and adding a loop checking isWifiConnected until it is false and that works!

So, for anyone having the same problem:
B4X:
    Dim success As Boolean = WiFi.disconnectWifiAP
    Log($"disconnectWifiAP = ${success}"$)
    Wifi_ConnectionResult(success)
    Do While WiFi.isWifiConnected = True
        Sleep(100)
    Loop

    'Now you can connect to your WiFi and it will work within the app
 
Upvote 0
Top