在 Android 中獲取網絡信號強度,需區分 WiFi 和移動網絡 (2G/3G/4G/5G) 使用不同 API,並注意權限與版本差異。
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeInfo = cm.getActiveNetworkInfo();
if (activeInfo == null || !activeInfo.isConnected()) {
// 無網絡連接
return;
}
int networkType = activeInfo.getType(); // TYPE_WIFI, TYPE_MOBILE 等
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
// 方法一:掃描結果獲取 (需位置權限 Android 6+)
List scanResults = wifiManager.getScanResults();
for (ScanResult result : scanResults) {
if (result.BSSID.equals(currentBSSID)) {
int level = result.level; // dBm 值,如 -50 到 -100
// 或使用 WifiManager.calculateSignalLevel(level, numLevels) 獲取 0-4 級
break;
}
}
// 方法二:當前連接信息 (API 23+ 推薦)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int rssi = wifiInfo.getRssi(); // dBm
int linkSpeed = wifiInfo.getLinkSpeed(); // Mbps
}
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
// API 31+ (Android 12) 統一 API
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// 需 READ_PHONE_STATE 權限
@SuppressLint("MissingPermission")
SignalStrength signalStrength = tm.getSignalStrength();
// 5G
if (signalStrength.isNr()) {
CellSignalStrengthNr nr = signalStrength.getCellSignalStrengths(CellSignalStrengthNr.class).get(0);
int ssRsrp = nr.getSsRsrp(); // dBm
}
// 4G
CellSignalStrengthLte lte = signalStrength.getCellSignalStrengths(CellSignalStrengthLte.class).get(0);
int rsrp = lte.getRsrp(); // dBm
int rsrq = lte.getRsrq(); // dB
// 3G/2G 類似...
}
// API 17-30 兼容方案
PhoneStateListener listener = new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
// 反射獲取私有方法或使用舊 API
// signalStrength.getGsmSignalStrength() 等
}
};
tm.listen(listener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
// 將 dBm 轉換為 0-4 級顯示圖標
public static int getSignalLevel(int rssi, int networkType) {
// WiFi: -50 優秀, -100 差
// 移動網絡: -80 優秀, -110 差 (視制式)
if (networkType == ConnectivityManager.TYPE_WIFI) {
return WifiManager.calculateSignalLevel(rssi, 5); // 0-4
} else {
// 移動網絡簡易分級
if (rssi >= -80) return 4;
else if (rssi >= -90) return 3;
else if (rssi >= -100) return 2;
else if (rssi >= -110) return 1;
else return 0;
}
}
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 移動網絡信號需此權限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 6+ WiFi 掃描需位置權限 -->
| Android 版本 | WiFi 獲取方式 | 移動網絡獲取方式 |
|---|---|---|
| API 1-22 | WifiManager.getScanResults() | PhoneStateListener + 反射 |
| API 23-30 | WifiManager.getConnectionInfo() | PhoneStateListener + SignalStrength 公開方法 |
| API 31+ | WifiManager.getConnectionInfo() | TelephonyManager.getSignalStrength() + CellSignalStrength 子類 |
ConnectivityManager cm = (ConnectivityManager) 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(@NonNull Network network) {
NetworkCapabilities nc = cm.getNetworkCapabilities(network);
if (nc != null) {
// nc.getSignalStrength() API 28+ 統一獲取信號強度
// nc.getTransportType() 判斷 TRANSPORT_WIFI / TRANSPORT_CELLULAR
}
}
// onLost, onCapabilitiesChanged...
});