B4A Library Simple WIFI library

NOTICE :

I am looking for someone to take over development and maintenance on this and other libraries. I am just no longer interested in programming and don't know how long I will feel that way. Anyone interested in taking over this library or any of my others, let me know a bit about yourself by email to [email protected]

Thanks,

--- Jem Miller

The Eclipse project and all source code has been attached below.


This is a very simple library that uses only 16 methods:

This is version 2.17. Don't panic, this version does not break anything!

I re-wrote the MACAddress method to handle Android M (API 23) and above. I also added the INTERNET and ACCESS_FINE_LOCATION permissions which seems to be required in API 23, and added a new method getAPI() that returns the version of Android running on the device as an integer.

SEE THE NEW WIFITEST EXAMPLE included in the zip file for examples of how to use this library.


MLwifi
Author:
Jem Miller - Missing Link Software
Version: 2.17
  • MLScan
    Events:
    • ScanDone (Results() As String, Count As Int)
    Fields:
    • wifis As String[]
      A string array containing all scanned access points in the area of the device.
      These are comma separated entries consisting of the following:
      SSID, Security type, signal strength, and "Saved" if this network was previously saved for use on this device.
    Methods:
    • Disconnect As Boolean
      Disconnects the current wifi AP connection
      Returns True on success
    • WifiCap (EntryNumber As Int) As String
      Returns a String containing info about the entry. A startScan must have already been done. The string contains the SSID, the BSSID, and the capabilities of the network access point.
      Each item is separated by a comma (SSID,BSSID,CapabilityString). The capabilities part can be quite long.
      EntryNumber - If you display the string array wifis or the array returned in the getWifiList method UNSORTED, you can pass the Position variable from your ListView_Click event.
      Otherwise, you must pass the entry number from the string array since that is what is used as a reference.
      Returns a string of comma separated entries of SSID,BSSID, and capability string. Returns an empty string on error.
    • addAP (EntryNumber As Int, securityType As String, Password As String) As Boolean
      Adds an entry to the wifi manager and connects to it. This method saves the configuration of the new entry onto the device. Use the forgetAP method to delete them. Updated to handle quoted or unquoted SSID strings.
      EntryNumber - If you display the string array wifis or the array returned in the getWifiList method UNSORTED, you can pass the Position variable from your ListView_Click event.
      Otherwise, you must pass the entry number from the string array since that is what is used as a reference.
      securityType - The Access Point security type (returned in the scan result string array)
      Password - The password/phrase for the wifi access point. Pass "" for an open network. Handles WEP HEX or text phrases
      It is up to you to supply all information. The security type is found in the scan results array.

      Returns True if the connection is successful
    • connectToAP (EntryNumber As Int) As Boolean
      Connects to a network already configured on the device. The device will use saved values to connect. Updated to handle quoted or unquoted SSID strings.
      EntryNumber - If you display the string array wifis or the array returned in the getWifiList method UNSORTED, you can pass the Position variable from your ListView_Click event.
      Otherwise, you must pass the entry number from the string array since that is what is used as a reference.
      Returns true if successful
    • forgetAP (NetId As Int) As Boolean
      Forgets (erases) a stored access point on the device.
      NetId - The network ID number to forget (returned in the listSavedNetworks method)
      Returns True if successful
    • getBSSID (EntryNumber As Int) As String
      Returns the BSSID for the selected entry.
      EntryNumber - If you display the string array wifis or the array returned in the getWifiList method UNSORTED, you can pass the Position variable from your ListView_Click event.
      Otherwise, you must pass the entry number from the string array since that is what is used as a reference.
    • isStored (EntryNumber As Int) As Boolean
      Checks the stored networks on the device to see if this entry is a previously saved access point
      EntryNumber - The entry number in the wifis array to check. If you display the string array wifis or the array returned in the getWifiList method UNSORTED, you can pass the Position variable from your ListView_Click event.
      Otherwise, you must pass the entry number from the string array since that is what is used as a reference.
      Returns True if this is a stored network
    • listSavedNetworks As List
      Builds a list of all saved networks on the device.
      Returns a comma separated list of SSID's and their BSSID and network ID number.
    • startScan (EventName As String)
      Initializes all objects and scans for wifi networks. Builds a string array of results (wifis) that can be accessed directly or with a call to updateWifiList.
      THIS METHOD SHOULD ONLY BE CALLED ONCE!
    • updateWifiList
      Call only after startScan has already been called and a string array of Access Points has been built. This method returns a string array containing the access points from the most recent scan, including background scans done automatically by the Android WifiManager. *
      Calls the ScanDone event when a new list is ready.
      Returns the string array of comma separated wifi access points by SSID. Each entry may contain the following:
      SSID, Security type, Signal level (in DB's), and the word "Saved" if the network was previously saved for use on this device.
    Properties:
    • LinkSpeed As Int [read only]
      Returns the LinkSpeed of the connected wifi access point
  • MLwifi
    Methods:
    • EnableWifi (Enabled As Boolean)
      Turns wifi on or off
      Pass True to enable wifi or False to disable.
      Example
      dim wifi as MLwifi
      wifi.EnableWifi(true)
    • IpAddress As String
      Get IP address from the wifi interface)
      Returns address or empty string
    • MACAddress As String
      Returns MAC address of the current interface

      Returns MAC address or empty string
    • SSID As String
      Returns the current SSID
    • WifiSignal As Int
      Returns the raw signal strength in decibels as an integer
      Returns 0 on error
    • WifiStrength As Int
      Returns an integer between 0 and 100 as a percentage of signal strength
      Returns 0 on error.
    • isOnLine As Boolean
      Checks for internet connection
      This method does not check or care what type of network is used.
      It can be wifi, 2g, 3g, 4g, wimax, etc. It just tests for internet connectivity.
      Returns True if internet is available.
    • isWifiConnected As Boolean
      Checks if wifi is connected. This only checks for wifi connection to a router.
      It does NOT test for internet availability. Use isOnLine() for that.
      Returns True if wifi is connected or False if 2g, 3g, 4g, wimax or no connection.
    Permissions:
    • android.permission.ACCESS_FINE_LOCATION
    • android.permission.ACCESS_NETWORK_STATE
    • android.permission.ACCESS_WIFI_STATE
    • android.permission.CHANGE_WIFI_STATE
    • android.permission.INTERNET
    Properties:
    • API As Int [read only]
      Returns the current devices Android API (the version of Android running on the device.) as an integer such as 19, 21, 23, etc.


There is a small test app included and a readme file as well. The whole mess is tiny and requires no other libs.

--- Jem

Version 1.00 - Initial release.

Version 1.01 - Added EnableWifi that I forgot in the initial release.

Version 1.02 - Using a different method to find IP address.

Version 1.03 - Adds getSSID

Version 1.04 - Removed "'s from getSSID. Renamed IsWifiConnected to isWifiConnected.

Version 1.05 - Adding AP scanning.

Version 1.06 - Adds getWifiSignal and getWifiStrength

Version 1.07 - Fixed an error in the test project and forced getSSID to return an empty string instead of Null if no SSID is found.

Version 2.00 - New connection manager methods in the MLScan class. Also changed the string array returned on a scan to include more information in a comma separated list of: SSID, security type, signal strength, and the word "Saved" if this network is saved on the device.

Version 2.01 - Added a new method WifiCap(SSID). This returns a string with comma separated fields of SSID, BSSID, and network capabilities. The capabilities refers to its security protocols. I also included a new version of the wifitest app. I forgot to add it to the version 2.00 library zip file. Tapping on a listed SSID will allow you to connect to that network.

Version 2.10 - Added Disconnect, isStored, and LinkSpeed and changed the way you must call several methods.

Version 2.11 - Removed WifiList and added updateWifiList. Fixed the connectToAP and isStored methods. Added a ScanDone event to automate scan results (no more timers needed). Added error correction and more speed.

Version 2.1.2 - Updated ScanDone event to allow real time scan results.

Version 2.13 - Updated the connect methods to handle either quoted or unquoted SSID values so in theory any version of the API should now work correctly for connecting to an AP.

Version 2.14 - Fixed the ConnectToAP method (Hopefully). Also updated the wifitest app to fix a few minor bugs.

Version 2.15 - Corrected a null pointer error if wifi is turned off during operation.

Version 2.16 - Added some error checking an changed the connecttoAP method slightly. It now checks both the SSID and BSSID to ensure that correct AP is connect to.

Version 2.17 - Added permissions for API 23, Re-wrote the MACAddress method so it returns a valid MAC address on Android M OR any lower version of Android. Added the getAPI method to get the current version of Android on the device.

.
 

Attachments

  • mlwifi-2.17.zip
    23.2 KB · Views: 2,247
  • mlwifi-src.zip
    16.4 KB · Views: 1,312
Last edited:

Mark Hollingworth

Member
Licensed User
Longtime User
I think this might be something to do with the Android version in question, I am testing on a real device running 5.1.1 and that's where I get the problem but if I run it on a device that is running Android Version 4.2.2 the error isn't happening and the .StartScan only returns one set of results..
 

HotShoe

Well-Known Member
Licensed User
Longtime User
The latest version I have is 5.0.1, but, I will see what I can find out on this end.

--- Jem
 

sorex

Expert
Licensed User
Longtime User
hey Shoe,

someone on the chat had issues to connect to access points with different phones so I installed the latest to test it myself.

when I connect to an AP it immediatly gives an error that it can't connect. works fine when I use the systems connect method tho.

Can you have a look at this pleas?
 

oceanwanderlust

Member
Licensed User
Longtime User
connectToAP does not work in my own code or the example

I am trying the example from v2.13 on my Droid Turbo which is still running Android 4.4.4, but every saved network I select on the list results in "Could not connect to"....

As @jjcc suggested, from Android I 'Forgot' one saved open network. When I ran the example again and clicked on this network, it did not display an error, but my IP became 0.0.0.0 SSID = <unknown ssid> and ever stranger Internet=true which is obviously wrong.

Edit: I tried the example on Android 5.1 but it still does not work.
 
Last edited:

HotShoe

Well-Known Member
Licensed User
Longtime User
Can you have a look at this pleas?

I'll do that, thanks.

As @jjcc suggested, from Android I 'Forgot' one saved open network. When I ran the example again and clicked on this network, it did not display an error, but my IP became 0.0.0.0 SSID = <unknown ssid> and ever stranger Internet=true which is obviously wrong.

I'll have another look at that method and see if I can find out what is happening.

--- Jem
 

HotShoe

Well-Known Member
Licensed User
Longtime User
New version posted in first message of this thread. Hopefully this fixes the connectToAP method for good.

--- Jem
 

HotShoe

Well-Known Member
Licensed User
Longtime User
MLscan is still there and unchanged. I just checked using the mlwifitest app and don't see anything missing. What are you seeing on your end?

--- Jem
 

davepamn

Active Member
Licensed User
Longtime User
I have a case where the wifi from the device becomes unavailable while the application is running. We turned the wifi off then on with the device. It seems like the application is jamming the socket. if I close and open the app then the socket becomes free. If I turn the wifi off then on the device frees. If I use your code to tell when the internet becomes unavailable then turn wifi off then back on, will it clear the socket.
 

DT1111

Member
Licensed User
Longtime User
Hello Jem, thanks for your MLWifi library and I have had good success with it where my app uses the lib to communicate with a wifi device which returns data.

Later I added a second wifi device where I have made the SSID, IP address and the port the same as the first.

The intention was to make the app requesting for data alternately between device 1 and device 2 on the same IP. But the app could only get response from just one device. My understanding was since the two devices are on the same IP address and with similar SSID, using the ConnectToAP method will open comm channel to both devices simultaneously and the devices will respond accordingly depending on what the app requests. Obviously it is not the case, it seems.

Do you know what the root cause may be?

Thanks.
 

HotShoe

Well-Known Member
Licensed User
Longtime User
To my knowledge, there is no way to connect 2 devices with the same IP address to the same network. The network must be able to route messages/data to the correct device via its IP address, so at least in my experience, it can't be done. Are you sure the router/access point isn't assigning a different address to the second device?

--- Jem
 

DT1111

Member
Licensed User
Longtime User
The IP address of the device can be manually configured and I chose to make them the same. Bad idea? The idea is the app broadcasts commands to these devices on the same IP network. My app is the master and the devices are the slaves per the master-slave model.

If I configured each device with a unique IP address, that would mean that the app has to connect to the first device via a unique IP, send a command, wait for response and then disconnect and connect to the second device via another unique IP, etc, etc and disconnect ... and so on. Is that the right approach? I hope not.
 

HotShoe

Well-Known Member
Licensed User
Longtime User
The IP address of the device can be manually configured and I chose to make them the same. Bad idea?

I didn't know that there was any access point or router that would allow that. Generally they will ignore the requested duplicate IP and issue a new one. You would need to check the IP on your devices after connecting to see if they are truly the same or not.

--- Jem
 

DT1111

Member
Licensed User
Longtime User
Thanks Jem.

Would you be able suggest a more decent approach to connecting with various IP devices with the Library. My concept below seems quite wrong and cumbersome. Thanks.

If I configured each device with a unique IP address, that would mean that the app has to connect to the first device via a unique IP, send a command, wait for response and then disconnect and connect to the second device via another unique IP, etc, etc and disconnect ... and so on. Is that the right approach? I hope not.
 

HotShoe

Well-Known Member
Licensed User
Longtime User
I think I would look at building a server side app on a single computer on that network to handle all of the needs of the app. Then all devices could connect to it via IP address and port and then issue commands. You could use B4J and include some type of security protocol if needed.

--- Jem
 

FrankBerra

Active Member
Licensed User
Longtime User
As reported by another user, sometimes i receive a strange error that crashes my app:
B4X:
10-17 13:49:48.240 16706 16706 E AndroidRuntime: FATAL EXCEPTION: main
10-17 13:49:48.240 16706 16706 E AndroidRuntime: Process: test.app, PID: 16706
10-17 13:49:48.240 16706 16706 E AndroidRuntime: java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.SCAN_RESULTS flg=0x4000010 (has extras) } in wifi.MLwifi$MLWifiScanner$WifiScanReceiver@63297bc
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:891)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.os.Looper.loop(Looper.java:148)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5417)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
10-17 13:49:48.240 16706 16706 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at wifi.MLwifi$MLWifiScanner.checkSSID(MLwifi.java:346)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at wifi.MLwifi$MLWifiScanner.access$0(MLwifi.java:339)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at wifi.MLwifi$MLWifiScanner$WifiScanReceiver.onReceive(MLwifi.java:324)
10-17 13:49:48.240 16706 16706 E AndroidRuntime:     at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:881)

How to reproduce the error:
- start a wifi scan and get the results
- turn off wifi
and after a couple of seconds my app crashes.
Android version: 5 and 6

Any suggestion?
Thanks
 
Last edited:

HotShoe

Well-Known Member
Licensed User
Longtime User
I think I know why and where that is happening. I'll look at it this evening.

Thanks

--- Jem
 

Sylwek

New Member
Licensed User
Longtime User
Hello,

I have a problem with addAP method. Everytime this method return false. I tried to check this method on example from v2.12, but still I have the same result.
I'm running on Android 4.2.2.

DO you have any suggestions ?
Thanks
 
Top