Android Code Snippet [B4X] Find all reachable ips in the local network

Slightly based on: https://stackoverflow.com/questions...me-wi-fi-network-in-android/21091575#21091575
Compatible with B4A and B4J.

Manifest editor (B4A only):
B4X:
AddPermission(android.permission.ACCESS_WIFI_STATE)
AddPermission(android.permission.INTERNET)

Depends on (j)Network library.
Code:
B4X:
Private Sub ScanNetwork
    Dim server As ServerSocket 'ignore
    Dim MyIp As String = server.GetMyIP
    If MyIp = "127.0.0.1" Then
        Log("Not connected to network.")
        Return
    End If
    Dim InetAddress As JavaObject
    InetAddress.InitializeStatic("java.net.InetAddress")
    Dim host As JavaObject = InetAddress.RunMethod("getByName", Array(MyIp))
    Dim ip() As Byte = host.RunMethod("getAddress", Null)
    Dim jME As JavaObject = Me
    For i = 1 To 254
        ip(3) = i
        Dim address As JavaObject = InetAddress.RunMethod("getByAddress", Array(ip))
        jME.RunMethod("checkAddress", Array(address, 300, False)) 'change to true to try and resolve host names. It will be a bit slower.
    Next
    For i = 1 To 254
        Wait For Address_Checked (HostAddress As String, Reachable As Boolean, HostName As String)
        If Reachable Then
            Log(HostAddress & ", " & HostName)
        End If
    Next
    Log("done")
End Sub


#if Java
public void checkAddress(java.net.InetAddress address, int timeout, boolean getHostName) {
    final String hostAddress = address.getHostAddress();
    BA.runAsync(getBA(), null, "address_checked", new Object[] {false, hostAddress, ""}, new java.util.concurrent.Callable<Object[]>() {
        public java.lang.Object[] call() throws Exception {
                if (address.isReachable(timeout))
                    return new Object[] {hostAddress, true, getHostName ? address.getHostName() : ""};
                else
                    return new Object[] {hostAddress, false, ""};
            }
            }
    
    );
}
#End If

This should be called from a class, such as B4XMainPage.
It runs pretty fast. Takes maybe 3 seconds to scan the network here (and it doesn't block the main thread).
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
<nit-picker:cool:>For /24 nets only, formally </nit-picker :cool: >
 

aminoacid

Active Member
Licensed User
Longtime User
There is an option to resolve host names. Based on my tests it is relevant for B4J (in B4A it will return the address immediately), but it is quite slow so I turned it off by default.

Help! I tried to figure out the option to resolve the hostnames but I give up! I have plenty of time to wait even if it's slow :D Thanks!
 

Knoppi

Active Member
Licensed User
Longtime User
I get a compiler error

B4X:
B4J Version: 10.20
Parsing code.    (0.00s)
    Java Version: 8
Building folders structure.    (0.01s)
Compiling code.    (0.00s)
Compiling layouts code.    (0.00s)
Organizing libraries.    (0.00s)
Compiling generated Java code.    Error
B4J line: 47
End Sub
javac 1.8.0_131
src\b4j\example\main.java:282: error: cannot find symbol
    BA.runAsync(getBA(), null, "address_checked", new Object[] {false, hostAddress, ""}, new java.util.concurrent.Callable<Object[]>() {
                ^
  symbol:   method getBA()
  location: class main
1 error
 

Knoppi

Active Member
Licensed User
Longtime User
main is also a class
B4X:
location: class main

i moved the code into a class module and it works
maybe main is a special class
 

LucaMs

Expert
Licensed User
Longtime User
main is also a class
B4X:
location: class main

i moved the code into a class module and it works
maybe main is a special class
1751526200410.png


Although modules in B4J are similar to classes, they handle events.
 

LucaMs

Expert
Licensed User
Longtime User
Here is a version generated (with difficulty) by ChatGPT.

I had it generate it because the Erel version gave me "wrong" results (currently I only have the PC connected via Ethernet and it did not return its IP but others of networks not currently used).
This version does not require jNetwork.

I have not tested this version in B4A.

B4X:
' Scans all local network interfaces and pings devices on each subnet
Public Sub ScanAllNetworks
    Log("🔍 Starting full network scan...")
   
    ' Get a list of (IP, interfaceName) pairs for all active IPv4 interfaces
    Dim Interfaces As List = GetLocalIPs
    If Interfaces.Size = 0 Then
        Log("⚠️ No valid local interfaces found.")
        Return
    End If
   
    For Each entry() As String In Interfaces
        Dim ip As String = entry(0).Trim
        Dim ifaceName As String = entry(1).Trim
        Log($"🌐 Scanning IP: ${ip} (Interface: ${ifaceName})"$)
       
        ' Split the IP string on the literal dot using Regex
        Dim parts() As String = Regex.Split("\.", ip)
        If parts.Length = 4 Then
            Dim subnet As String = $"${parts(0)}.${parts(1)}.${parts(2)}."$
            Log("📡 Subnet: " & subnet)
            ScanSubnet(subnet)
        Else
            Log("⚠️ Invalid IP format: " & ip)
        End If
    Next

    Log("✅ All subnet scans completed.")
End Sub

' Scans a given /24 subnet by pinging addresses .1 to .254
Private Sub ScanSubnet(subnet As String)
    For i = 1 To 254
        Dim targetIp As String = subnet & i
        CheckHost(targetIp, 300, False)
    Next

    For i = 1 To 254
        Wait For Address_Checked (HostAddress As String, Reachable As Boolean, HostName As String)
        If Reachable Then Log("🟢 Reachable: " & HostAddress)
    Next
End Sub

' Calls Java code asynchronously to ping one IP
Private Sub CheckHost(Ip As String, Timeout As Int, GetHostName As Boolean)
    Dim joInet As JavaObject
    joInet.InitializeStatic("java.net.InetAddress")
    Dim address As JavaObject = joInet.RunMethod("getByName", Array(Ip))
    Dim jMe As JavaObject = Me
    jMe.RunMethod("checkAddress", Array(address, Timeout, GetHostName))
End Sub

' Returns a list of (IP, interfaceName) for each active IPv4 interface
Private Sub GetLocalIPs As List
    Dim result As List
    result.Initialize

    Dim niClass As JavaObject
    niClass.InitializeStatic("java.net.NetworkInterface")
    Dim enumIfs As JavaObject = niClass.RunMethod("getNetworkInterfaces", Null)

    Do While enumIfs.RunMethod("hasMoreElements", Null)
        Dim intf As JavaObject = enumIfs.RunMethod("nextElement", Null)
        If intf.RunMethod("isUp", Null) = False Then Continue
        If intf.RunMethod("isLoopback", Null) = True Then Continue

        Dim enumAddrs As JavaObject = intf.RunMethod("getInetAddresses", Null)
        Do While enumAddrs.RunMethod("hasMoreElements", Null)
            Dim addr As JavaObject = enumAddrs.RunMethod("nextElement", Null)
            Dim ip As String = addr.RunMethod("getHostAddress", Null)
            If ip.StartsWith("127.") Then Continue
            If ip.Contains(":") Then Continue ' Skip IPv6
            result.Add(Array As String(ip, intf.RunMethod("getName", Null)))
        Loop
    Loop

    Return result
End Sub

#If Java
// Asynchronously checks reachability of an IP and raises Address_Checked event
public void checkAddress(java.net.InetAddress address, int timeout, boolean getHostName) {
    final String hostAddress = address.getHostAddress();
    BA.runAsync(getBA(), null, "address_checked", new Object[] {false, hostAddress, ""}, new java.util.concurrent.Callable<Object[]>() {
        public Object[] call() throws Exception {
            if (address.isReachable(timeout))
                return new Object[] {hostAddress, true, getHostName ? address.getHostName() : ""};
            else
                return new Object[] {hostAddress, false, ""};
        }
    });
}
#End If
 
Top