Android 局域网 IP 扫描实现指南

在现代移动应用开发中,局域网内设备的扫描功能常常是一个非常实用的需求。本文将为刚入行的小白开发者讲解如何在 Android 中实现局域网的 IP 扫描功能。

1. 整体流程

在开始之前,我们需要理清实现的步骤。下面是整体流程的简要概述:

步骤 描述
1 创建 Android 项目
2 获取当前设备的局域网 IP
3 确定 IP 范围
4 执行网络扫描
5 显示扫描结果

2. 各步骤的详细操作

步骤 1:创建 Android 项目

首先,你需要在 Android Studio 中创建一个新的项目。

  1. 打开 Android Studio,点击 **"新建项目"**。
  2. 选择 "空活动" 模板。
  3. 配置项目名称和包名,然后完成创建。

步骤 2:获取当前设备的局域网 IP

要扫描局域网中的设备,首先你需要获取设备的局域网 IP。确保在 AndroidManifest.xml 中申请网络权限。

<manifest xmlns:android="
    package="com.example.networkscanner">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
</manifest>

然后,你可以在主要活动中获取设备的 IP 地址:

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.wifi.WifiManager;
import java.util.List;

public class NetworkUtil {
    // 获取设备的本地 IP 地址
    public static String getLocalIpAddress(Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        int ip = wifiManager.getConnectionInfo().getIpAddress();
        return String.format("%d.%d.%d.%d", (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
    }
}

注释:此代码使用 WifiManager 获取设备的 IP 地址,将其转换为标准的点分十进制格式。

步骤 3:确定 IP 范围

通常局域网 IP 地址的格式为 192.168.x.x。你可以使用以下方法确定要扫描的 IP 范围。

public static String[] getIpRange(String localIp) {
    String baseIp = localIp.substring(0, localIp.lastIndexOf('.') + 1);
    String[] ipRange = new String[255];
    for (int i = 1; i <= 254; i++) {
        ipRange[i - 1] = baseIp + i;
    }
    return ipRange;
}

注释:此代码通过本地 IP 地址生成再用于扫描的 IP 列表。

步骤 4:执行网络扫描

使用 Java 的 InetAddress 类来检查各个 IP 地址的可达性。

import java.net.InetAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NetworkScanner {
    private ExecutorService executor = Executors.newFixedThreadPool(10);
    
    public void scan(String[] ipRange) {
        for (String ip : ipRange) {
            executor.submit((Callable<Void>) () -> {
                try {
                    if (InetAddress.getByName(ip).isReachable(1000)) {
                        System.out.println("发现设备: " + ip);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            });
        }
    }
}

注释:此代码为每个 IP 地址创建一个新的任务,尝试通过 isReachable 方法检查该 IP 是否在线。

步骤 5:显示扫描结果

最后,你可以将结果显示在 RecyclerView 或 ListView 中。这里只给出一个简单的 Console 输出示例。你可以将结果存储在一个列表中,然后更新 UI。

public class MainActivity extends AppCompatActivity {
    private TextView resultTextView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        resultTextView = findViewById(R.id.text_view_results);
        
        String localIp = NetworkUtil.getLocalIpAddress(this);
        String[] ipRange = NetworkUtil.getIpRange(localIp);
        NetworkScanner scanner = new NetworkScanner();
        scanner.scan(ipRange);
    }
}

注释:设置 UI 组件并启动扫描过程。

ER 图

以下是相关实体间的关系图,展示了网络扫描时的实体关系。

erDiagram
    NETWORK_SCANNER {
        int id
        string ipAddress
    }

    DEVICE {
        int id
        string ipAddress
        boolean isReachable
    }

    NETWORK_SCANNER ||--o{ DEVICE : scans

类图

以下是系统中主要类的类图,展示了它们之间的关系。

classDiagram
    class NetworkUtil {
        +String getLocalIpAddress(Context context)
        +String[] getIpRange(String localIp)
    }

    class NetworkScanner {
        +void scan(String[] ipRange)
    }

    class MainActivity {
        +void onCreate(Bundle savedInstanceState)
    }

    NetworkUtil -- NetworkScanner : uses
    MainActivity --> NetworkUtil : uses
    MainActivity --> NetworkScanner : initiates

结束语

通过上面的步骤,你应该能够实现一个 Android 应用来扫描局域网内的设备。本文涵盖了获取 IP 地址、确定扫描范围、执行网络扫描和显示结果的完整过程。希望这篇文章能帮助到你,鼓励你在实际开发中不断尝试和探索更多功能!如果有任何问题,欢迎交流讨论。