Android 應用需實現:獲取手機當前 IP(適配 WiFi/移動網絡切換),以及網絡斷開時通知 Activity。核心 API 涉及 WifiManager、ConnectivityManager 與廣播機制。
優先使用 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
}
}
}
}
}
採用動態註冊廣播接收器監聽 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
WifiManager 部分信息,建議改用 ConnectivityManager.NetworkCallback API。
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/移動網絡兩套邏輯。