Bug? Simple Wifi (MLWifi) not working correctly with Android 9

Computersmith64

Well-Known Member
Licensed User
Longtime User
As was reported in this thread, the MLWifi library does not work correctly in apps running on Android 9 devices. I have tested with a small B4A app connecting to a small B4R app running on a Wemos D1R2 board (both projects attached) & found that even when the B4A app is connected to the B4R access point, MLWifi reports isWifiConnected as False. This happens regardless of whether the Android device is already connected to the AP before the app runs, or whether the app makes the connection. The issue is not that the app can't connect to the AP - the issue is that MLWifi incorrectly reports as not being connected.

On a pre-Android 9 device it works fine (as I have proven with multiple B4R/B4A projects I have written).

The 2 projects are attached for your testing pleasure...
 

Attachments

  • B4A_AP_Test.zip
    8.5 KB · Views: 470
  • B4R_AP_Test.zip
    1.2 KB · Views: 424
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
As was reported in this thread, the MLWifi library does not work correctly in apps running on Android 9 devices. I have tested with a small B4A app connecting to a small B4R app running on a Wemos D1R2 board (both projects attached) & found that even when the B4A app is connected to the B4R access point, MLWifi reports isWifiConnected as False. This happens regardless of whether the Android device is already connected to the AP before the app runs, or whether the app makes the connection. The issue is not that the app can't connect to the AP - the issue is that MLWifi incorrectly reports as not being connected.

On a pre-Android 9 device it works fine (as I have proven with multiple B4R/B4A projects I have written).

The 2 projects are attached for your testing pleasure...

Hi, I have tested your project on a Samsung Galaxy 8+ with Android 9 and is WIFIConnected works correctly.
Even if the mobile data is stopped or the location.

I have placed at the beginning of Public Sub ConnectToAP

B4X:
LogColor ("testWiFi.isWifiConnected" & testWiFi.isWifiConnected, Colors.Blue)


And it returns TRUE


regards
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hi, I have tested your project on a Samsung Galaxy 8+ with Android 9 and is WIFIConnected works correctly.
Even if the mobile data is stopped or the location.

I have placed at the beginning of Public Sub ConnectToAP

B4X:
LogColor ("testWiFi.isWifiConnected" & testWiFi.isWifiConnected, Colors.Blue)


And it returns TRUE


regards
Per my last reply to your PMs, it still does not work if the connected AP is not also connected to the internet.

- Colin .
 

OliverA

Expert
Licensed User
Longtime User
Update: As of right now (until I fix this), this code is bullocks. Please ignore. See post below this for more info.
Update2: Fix is in link #6. Usage is still the same as explained here (without the need of worrying about API levels though).

Add the class code below to your test project. I named the class CheckWifi. Usage would be
B4X:
Dim cWifi As CheckWifi
Log("Wifi Status: " & cWifi.isWifiConnected)
The only difference here and the library is that this class uses newer (API 21 and up) methods for detecting the WiFi status. Looking at the code of the Simple Wifi library, the isWifiConnnected method uses API's that will be deprecated in API 28 and API Q. Maybe the older API calls work just a tad different under Pie (should not, buy maybe).
New class code:
B4X:
Sub Class_Globals
 
End Sub
'Note: Need this in Manifest
' AddPermission(android.permission.ACCESS_NETWORK_STATE)

Public Sub Initialize

End Sub

Public Sub isWifiConnected() As Boolean
   Dim phoneInstance As Phone
   If phoneInstance.SdkVersion >= 21 Then
       Dim jo As JavaObject = Me
       Dim r As Reflector
       Return jo.RunMethod("isWiFiUp", Array(r.GetContext))
   Else
       Log("This method requires SKD version 21 and above!")
       Return False
   End If
End Sub

#if JAVA

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;

public boolean isWiFiUp(Context context) {
   boolean connected = false;

   //https://stackoverflow.com/a/32771164
   ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
   if (activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) connected = true;

   return connected;
}

#End If
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
As of now, ignore the post above. My initial code did not work as I wanted and what I ended up with (inadvertently) is pretty much the same code as is in the library (with the same future API deprecation issues). What a facepalm
 

OliverA

Expert
Licensed User
Longtime User
it still does not work if the connected AP is not also connected to the internet.

Ok, below is the fixed class code. It's pretty much a straight copy from a stackoverlfow post (link in source). It should work with all versions of Android as of now (and at least through Q). Try it and let me know if it works for your scenario.

B4X:
Sub Class_Globals
  
End Sub

'Note: Need this in Manifest
' AddPermission(android.permission.ACCESS_NETWORK_STATE)

Public Sub Initialize

End Sub

Public Sub isWifiConnected() As Boolean
   Dim jo As JavaObject = Me
   Dim r As Reflector
   Return jo.RunMethod("isNetworkConnected", Array(r.GetContext))
End Sub

#if JAVA

import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Build;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkCapabilities;

//import anywheresoftware.b4a.BA;

//Pretty much a straight rip from https://stackoverflow.com/a/53078141
public boolean isNetworkConnected(Context context) {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
           //BA.Log("Build SDK < 23");
            NetworkInfo ni = cm.getActiveNetworkInfo();
            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI));
            }
        } else {
           //BA.Log("Build SDK >= 23");
            Network n = cm.getActiveNetwork();
            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);
                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        }
    }
    return false;
}

#End If
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Thanks - I'm out of the country at the moment & not back for about another week, so I'll take a look at it then .

- Colin.
 

Computersmith64

Well-Known Member
Licensed User
Longtime User
Ok, below is the fixed class code. It's pretty much a straight copy from a stackoverlfow post (link in source). It should work with all versions of Android as of now (and at least through Q). Try it and let me know if it works for your scenario.

B4X:
Sub Class_Globals
 
End Sub

'Note: Need this in Manifest
' AddPermission(android.permission.ACCESS_NETWORK_STATE)

Public Sub Initialize

End Sub

Public Sub isWifiConnected() As Boolean
   Dim jo As JavaObject = Me
   Dim r As Reflector
   Return jo.RunMethod("isNetworkConnected", Array(r.GetContext))
End Sub

#if JAVA

import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Build;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkCapabilities;

//import anywheresoftware.b4a.BA;

//Pretty much a straight rip from https://stackoverflow.com/a/53078141
public boolean isNetworkConnected(Context context) {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
           //BA.Log("Build SDK < 23");
            NetworkInfo ni = cm.getActiveNetworkInfo();
            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI));
            }
        } else {
           //BA.Log("Build SDK >= 23");
            Network n = cm.getActiveNetwork();
            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);
                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        }
    }
    return false;
}

#End If
Thanks for all your effort on this - however your isNetworkConnected function also reports false if connecting to an AP that's not also connected to the internet. If my Android 9 device is already connected to my home Wifi (which has an internet connection), isNetworkConnected (& MLWifi.isWifiConnected) will report true - however if connected to my ESP8266 access point (which doesn't have internet), both functions always report false. Even if I completely disable my home Wifi & the only possible AP to connect to is my ESP8266, I still can't get a true isWifiConnected or isNetworkConnected result - regardless if the device is already connected to the AP, or the app connects it.

It works fine on my KitKat device.

I'm starting to wonder if this is a bug in Pie...?

- Colin.
 
Top