Android Question How does MLWifi actually work?

JMB

Active Member
Licensed User
Hi

I've been having lots of fun and games trying to connect between different Wifi SSIDS and I am somewhat confused (my usual state these days) and I am posting this to try and see if others can shed some light. My sincere thanks to contributors who have helped me get this far via other threads.

The example I have posted uses the MLwifi library.

It's pretty simple. Once it has set some required permissions, it gets a list of all the known access points on the device, then shows them in a list.

If the user selects one, it tries to connect to it. There are lots of log messages to try and show me what's going on. As you can see from the code, it makes sure a disconnect occurs before an attempt to connect is made.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
   
    Dim myMLWifiObject As MLwifi
    Dim myMLScan As MLScan
    Dim rp As RuntimePermissions
    Type SSIDentry (SSID As String, BSSID As String, Index As String)
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private ListView1 As ListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("1")
    If FirstTime Then       
        Dim numberOfValidPermissions As Int = 0
        rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
        wait for Activity_PermissionResult (Permission As String, Result As Boolean)
        If Result Then
            ' Fine location permission OK
            numberOfValidPermissions = numberOfValidPermissions +1
        End If
        rp.CheckAndRequest(rp.PERMISSION_ACCESS_COARSE_LOCATION)
        wait for Activity_PermissionResult (Permission As String, Result As Boolean)
        If Result Then
            ' COARSE location permission OK
            numberOfValidPermissions = numberOfValidPermissions + 1
        End If
        If numberOfValidPermissions = 2 Then
            Log("   ")
                Log("Doing the Scan...")
                myMLScan.startscan("wifi",False)
        Else
            Log("Permission not set")
        End If
    End If
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub wifi_ScanDone(Results() As String, Count As Int)
    Dim record As SSIDentry
    record.initialize
   
    Dim ListForList As List
    ListForList.Initialize
   
    Dim listofNetworks As List
    listofNetworks = myMLScan.listSavedNetworks
       
    Dim returnedEntry() As String
    For i = 0 To listofNetworks.Size-1
        returnedEntry = Regex.Split(",",listofNetworks.Get(i))
       
        record.ssid = returnedEntry(0).SubString2(1,returnedEntry(0).Length-1) 'Remove the quotes
        record.bssid = returnedEntry(1)
        record.index = returnedEntry(2)
       
        ListView1.AddTwoLines2(record.SSID,record.Index,record.SSID)
       
    Next
End Sub

Sub ListView1_ItemClick (Position As Int, Value As Object)
   
    Private connectionStart As Long = DateTime.Now
    Private connectionTimeOut As Long = 30000
   
    Dim selectedSSID As String
   
    selectedSSID = Value
    ToastMessageShow(selectedSSID,False)
   
    myMLWifiObject.disconnectWifiAP
    connectionStart = DateTime.Now
    Do Until myMLWifiObject.isWifiConnected = False
        Log("Waiting for Disconnect..." & (DateTime.Now - (connectionStart + connectionTimeOut)))
        Sleep(0)
        If DateTime.Now > connectionStart + connectionTimeOut Then
            Log("DISCONNECT FAILED")
            Return
        End If
    Loop
       
    Log("Call to connect to " & selectedSSID & " returned " & myMLWifiObject.connectWifiAP(selectedSSID))
    Log("The current SSID is " & myMLWifiObject.WifiSSID)
   
    connectionStart = DateTime.Now
    Do Until myMLWifiObject.isWifiConnected
        Log("Waiting for MLWifi to connect..." & (DateTime.Now - (connectionStart + connectionTimeOut)))
        Sleep(0)
        If DateTime.Now > connectionStart + connectionTimeOut Then
            Log("CONNECTION FAILED")
            Log("Now MLwifi is connected to " & myMLWifiObject.WifiSSID)
            Return
        End If
    Loop
    Log("Managed to connect to " & myMLWifiObject.WifiSSID)
    Log("Asked to connect to " & selectedSSID)
    If myMLWifiObject.WifiSSID <> selectedSSID Then
        Log("Wrong SSID!!!")
    Else
        Log("Correct SSID - hurrah")
    End If
    ToastMessageShow(myMLWifiObject.ActiveNetworkTypeName,False)
   
End Sub

What I don't fully understand is that it doesn't appear to do what it is told.

The main action is in
B4X:
Sub ListView1_ItemClick (Position As Int, Value As Object)

For example, I have a couple of SSIDs available in the house. If I select one of them, it connects absolutely fine. If I then try and connect to the other one, it doesn't. Or it connects - but to the one that it was connected to before.

And if I select an SSID from the list which is not one of the networks which is available in the house, it connects to a house network anyway!

Is there some underlying android network behaviour that I am missing here, because at the moment, the behaviour of this library seems unpredictable.

I just want to be able to reliable switch between networks that I know exist, or if the network doesn't exist, be made aware of that so I can deal with it in a controlled manner.

Thanks for any hints.

JMB
 

Computersmith64

Well-Known Member
Licensed User
Some Android devices have a function that will automatically switch to the strongest Wifi signal available (or switch between cellular data & Wifi depending on which has a stronger signal). Make sure that's not the case with your device.

Another possibility - I'm sure I read somewhere that MLWifi will only connect to SSIDs that are already in the preferred network list on the device, so make sure that the SSID you are trying to connect to is a remembered network on the device itself.

Also, you don't need to both FINE & COARSE location permissions (https://developers.google.com/maps/documentation/android-sdk/location) - in fact I'm not even sure you need to request those permissions at all in this case. I use MLWifi in one of my apps & I don't see the requirement for the location permission.

- Colin.
 
Upvote 0

JMB

Active Member
Licensed User
Thanks, Colin. I shall look into that.

The networks I am trying to connect to have been used before.

I just can't figure out how to reliably connect and disconnect from an Access Point at the moment.
 
Upvote 0

werner_Fourie

Member
Licensed User
Hi To All..

I have noticed that the first saved AP location is a problem..
if the {record.index = returnedEntry(2)} = 0 it does not automatically connect to that AP at all..
It will only connect through Android.

record.ssid = Test_AP
record.bssid = any
record.index = 0

Above = problem

record.ssid = Test_AP
record.bssid = any
record.index = 1

Above works
Once I place a dummy AP at location 0 it works fine...

Hope this helps..
 
Upvote 0
Top