首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 實現持續聯網監測:IP 獲取與網絡變化通知

     編輯:程式設計綜合問答

Android 應用需實現:獲取手機當前 IP(適配 WiFi/移動網絡切換),以及網絡斷開時通知 Activity。核心 API 涉及 WifiManager、ConnectivityManager 與廣播機制。

1. 獲取當前 IP 地址

優先使用 ConnectivityManager 獲取活躍網絡信息,再根據類型提取 IP:


// 獲取 ConnectivityManager
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

if (activeNetwork != null && activeNetwork.isConnected()) {
    if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
        // WiFi 下用 WifiManager 獲取 DHCP 信息
        WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        DhcpInfo dhcp = wm.getDhcpInfo();
        int ipAddress = dhcp.ipAddress; // int 型,需轉換為 x.x.x.x 格式
        // 同理可獲取 gateway, netmask, dns1, dns2
    } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // 移動網絡遍歷 NetworkInterface 獲取 IP
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface ni = interfaces.nextElement();
            Enumeration<InetAddress> addresses = ni.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress addr = addresses.nextElement();
                if (!addr.isLoopbackAddress() && addr instanceof Inet4Address) {
                    String ip = addr.getHostAddress(); // 即為移動網絡 IP
                }
            }
        }
    }
}

2. 監聽網絡變化並通知 Activity

採用動態註冊廣播接收器監聽 CONNECTIVITY_ACTION:


// 定義廣播接收器
public class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        boolean hasNetwork = (info != null && info.isConnected());
        // 發送本地廣播或回調通知 Activity
        Intent localIntent = new Intent("NETWORK_CHANGE");
        localIntent.putExtra("hasNetwork", hasNetwork);
        LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);
    }
}

// Activity 中註冊
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new NetworkChangeReceiver(), filter);
// 或使用 LocalBroadcastManager 註冊自定義 Action

3. 適配 Android 7.0+ 限制

  • Android 7.0 (API 24) 起,靜態註冊CONNECTIVITY_ACTION 無效,必須動態註冊。
  • Android 10 (API 29) 限制非系統應用訪問 WifiManager 部分信息,建議改用 ConnectivityManager.NetworkCallback API。

現代寫法:NetworkCallback (API 21+)


ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .build();

cm.registerNetworkCallback(request, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // 網絡可用
    }
    @Override
    public void onLost(Network network) {
        // 網絡斷開
    }
    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
        // 獲取 IP 等信息
        LinkProperties lp = cm.getLinkProperties(network);
        List<LinkAddress> addresses = lp.getLinkAddresses();
    }
});

總結:優先用 NetworkCallback 替代舊廣播,兼容性更好、功能更豐富;IP 獲取需區分 WiFi/移動網絡兩套邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved