Android Code Snippet WifiNetworkSpecifier + NetworkRequest - connect app to specific wifi network

Requires Android 10+ (api level 29+).

Allows your app to connect to a specific network, provided by its SSID and password. Note that this makes a local connection, which means that only your app will use this network.
The user will need to approve the connection on the first time.

Manifest editor:
B4X:
AddPermission("android.permission.CHANGE_NETWORK_STATE")

Code (in a class module such as B4XMainPage):

B4X:
Private Sub ConnectToNetwork (SSID As String, Password As String, TimeoutMs As Int) As ResumableSub
    Dim builder As JavaObject
    builder.InitializeNewInstance("android.net.wifi.WifiNetworkSpecifier.Builder", Null)
    builder.RunMethod("setSsid", Array(SSID))
    builder.RunMethod("setWpa2Passphrase", Array(Password))
    Dim specifier As JavaObject = builder.RunMethod("build", Null)
    Dim RequestBuilder As JavaObject
    RequestBuilder.InitializeNewInstance("android.net.NetworkRequest.Builder", Null)
    RequestBuilder.RunMethod("addTransportType", Array(1)) 'TRANSPORT_WIFI
    RequestBuilder.RunMethod("setNetworkSpecifier", Array(specifier))
    Dim NetworkRequest As JavaObject = RequestBuilder.RunMethod("build", Null)
    Dim context As JavaObject
    context.InitializeContext
    Dim cm As JavaObject = context.RunMethod("getSystemService", Array("connectivity"))
    Dim callback As JavaObject
    callback.InitializeNewInstance(GetType(Me) & "$MyNetworkCallback", Array(Me))
    cm.RunMethod("requestNetwork", Array(NetworkRequest, callback, TimeoutMs))
    Wait For Network_State (Available As Boolean, Network As Object)
    Log("Available? " & Available)
    
    If Available Then
        cm.RunMethod("bindProcessToNetwork", Array(Network))
    End If
    Return Available
End Sub

#if Java
public static class MyNetworkCallback extends android.net.ConnectivityManager.NetworkCallback {
    private final BA ba;
    public MyNetworkCallback(B4AClass me) {
        this.ba = me.getBA();
    }
    @Override
        public void onAvailable(android.net.Network network) {
            super.onAvailable(network);
            BA.Log("Network available: " + network);
            ba.raiseEvent(this, "network_state", true, network);
        }
        @Override
        public void onUnavailable() {
            super.onUnavailable();
            BA.Log("Network onUnavailable");
            ba.raiseEvent(this, "network_state", false, null);
        }
}
#End If

Usage:
B4X:
Wait For (ConnectToNetwork("ssid here", "and password")) Complete (Success As Boolean)
'Try to make the request even if Success is False. It might still work.
    Dim job As HttpJob
    job.Initialize("", Me)
    job.Download("https://www.google.com")
    Wait For (job) JobDone(job As HttpJob)
    If job.Success Then
       Log(job.GetString)
    End If
    job.Release
 
Last edited:

vinpolins

Member
The Wifi is connected as expected.

But for some reason, the line #18 does not return: Wait For Network_State (Available As Boolean, Network As Object)
Therefore the line #19 was not called: Log("Available? " & Available)

Any idea?
 

vinpolins

Member
Add a log method to the two inline methods:
B4X:
BA.Log("onAvailable"); //and onUnavailable for the second one

Do you see these messages?
No messages either.
The Wifi is still connected as expected.

Here is the code as you instructed:
B4X:
#If Java
public static class MyNetworkCallback extends android.net.ConnectivityManager.NetworkCallback {
    private final BA ba;
    public MyNetworkCallback(B4AClass me) {
        this.ba = me.getBA();
    }
    @Override
        public void onAvailable(android.net.Network network) {
            BA.Log("onAvailable");
            super.onAvailable(network);
            ba.raiseEvent(this, "network_state", true, network);
        }
        @Override
        public void onUnavailable() {
            BA.Log("onUnavailable");
            super.onUnavailable();
            ba.raiseEvent(this, "network_state", false, null);
        }
}
#End If
 

vinpolins

Member
MORE INFORMATION:
When call the Sub ConnectToNetwork, the app will show the dialog asking if user want to the network. As you said above: "The user will need to approve the connection on the first time."

- If I click Connect, the Wifi is connected but onAvailable does NOT fires.
- If I click Cancel, the Wifi will not connect but onUnavailable will FIRES. Very strange!

Any ideas?
 
Top