NetworkInfo 和 WifiConfiguration 已在 SDK 22 中弃用
NetworkInfo and WifiConfiguration has been deprecated in SDK 22
我在 PAX A920 设备(SDK 版本 22)中使用 android lollipop。我在构建时收到这样的警告消息:
NetworkInfo in android.net has been deprecated
WifiConfiguration in android.net has been deprecated
我很困惑,因为我在 C:\Users\{YOUR_ACCOUNT}\AppData\Local\Android\Sdk\sources\android-22\com\android\connectivitymanagertest
中看到了使用该方法访问 wifi 的 sdk 22 示例,但为什么它似乎已被弃用?
有什么方法可以替代已弃用的方法?
public boolean isWifiConnected() {
boolean isWifiConnected = false;
try {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo != null) {
isWifiConnected = networkInfo.getState() == CONNECTED;
}
Log.i(TAG, "wifi adapter is connected? " + isWifiConnected);
} catch (Exception ex) {
ex.printStackTrace();
}
return isWifiConnected;
}
public void removeNetwork() {
List<WifiConfiguration> wifiCfgList = wifiManager.getConfiguredNetworks();
if (wifiCfgList.size() > 0) {
for (WifiConfiguration item : wifiCfgList) {
if (item != null) {
wifiManager.removeNetwork(item.networkId);
wifiManager.saveConfiguration();
}
}
}
}
感谢指出。
已弃用的 classes 已替换为 ConnectivityManager
系统服务和 NetworkCallbacks
:https://developer.android.com/training/monitoring-device-state/connectivity-status-type
尽管官方代码示例显示了如何从 ConnectivityManager
获取 NetworkInfo
,但有一个突出显示的注释:
这是一个示例代码,说明您如何获取当前网络状态并随着时间的推移接收更新。这是我将在生产中使用的部分精简的解决方案。如果您将它与 RxJava 或 RxKotlin 连接,您可以创建一个可观察对象来保存网络状态,并在调用 NetworkCallback 的重写方法时进行更新。
关于 Java 的注意事项:public class 级变量被设为 public 只是为了简洁。相反,我会为它们创建一些 getter 来访问这些变量背后的值。
欢迎提问。
Java
class NetworkReachabilityService {
public NetworkType networkType;
public NetworkState networkState = NetworkState.Unavailable;
private ConnectivityManager connectivityManager;
private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
updateAvailability(connectivityManager.getNetworkCapabilities(network));
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
networkState = NetworkState.Losing;
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
networkState = NetworkState.Lost;
}
@Override
public void onUnavailable() {
super.onUnavailable();
networkState = NetworkState.Unavailable;
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
updateAvailability(networkCapabilities);
}
};
public NetworkReachabilityService(Context context) {
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
private void updateAvailability(NetworkCapabilities networkCapabilities) {
if (networkCapabilities == null) {
networkState = NetworkState.Unavailable;
return;
}
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
networkType = NetworkType.CELL;
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
networkType = NetworkType.WiFi;
}
networkState = NetworkState.Available;
}
public void resumeListeningNetworkChanges() {
pauseListeningNetworkChanges();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback);
} else {
connectivityManager.registerNetworkCallback(
new NetworkRequest.Builder().build(),
networkCallback
);
}
}
public void pauseListeningNetworkChanges() {
try {
connectivityManager.unregisterNetworkCallback(networkCallback);
} catch (IllegalArgumentException exception) {
// Usually happens only once if: "NetworkCallback was not registered"
}
}
private enum NetworkState {
Available, Unavailable, Connecting, Losing, Lost
}
private enum NetworkType {
WiFi, CELL, OTHER
}
}
科特林
sealed class NetworkState {
data class Available(val type: NetworkType) : NetworkState()
object Unavailable : NetworkState()
object Connecting : NetworkState()
object Losing : NetworkState()
object Lost : NetworkState()
}
sealed class NetworkType {
object WiFi : NetworkType()
object CELL : NetworkType()
object OTHER : NetworkType()
}
class NetworkReachabilityService private constructor(context: Context) {
private val connectivityManager: ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
// There are more functions to override!
override fun onLost(network: Network) {
super.onLost(network)
networkState = NetworkState.Lost
}
override fun onUnavailable() {
super.onUnavailable()
networkState = NetworkState.Unavailable
}
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
networkState = NetworkState.Losing
}
override fun onAvailable(network: Network) {
super.onAvailable(network)
updateAvailability(connectivityManager.getNetworkCapabilities(network))
}
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
updateAvailability(networkCapabilities)
}
}
var networkState: NetworkState = NetworkState.Unavailable
private set
private fun updateAvailability(networkCapabilities: NetworkCapabilities?) {
if (networkCapabilities == null) {
networkState = NetworkState.Unavailable
return
}
var networkType: NetworkType = NetworkType.OTHER
if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
networkType = NetworkType.CELL
}
if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) {
networkType = NetworkType.WiFi
}
networkState = NetworkState.Available(networkType)
}
fun pauseListeningNetworkChanges() {
try {
connectivityManager.unregisterNetworkCallback(networkCallback)
} catch (e: IllegalArgumentException) {
// Usually happens only once if: "NetworkCallback was not registered"
}
}
fun resumeListeningNetworkChanges() {
pauseListeningNetworkChanges()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback)
} else {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(),
networkCallback
)
}
}
}
要开始接收网络状态更新,请分别调用 resumeListeningNetworkChanges
和停止 pauseListeningNetworkChanges
。
更新:如何在已弃用的和新的之间切换 API
请注意,即使您使用此解决方案,您仍然会收到一条消息,表明您使用的特定代码已被弃用!它完全没问题,只要您提供一个可以在新 API 和旧的、已弃用的 API.
之间切换的实现,就不会被视为错误。
这是一个近似解。由于新的 classes 是在 API 级别 29 中添加的,我们必须使用 Build.VERSION_CODES.Q
因为它是一个整数,其值为 29
.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Use new API here
} else {
// Use old API here
}
我在 PAX A920 设备(SDK 版本 22)中使用 android lollipop。我在构建时收到这样的警告消息:
NetworkInfo in android.net has been deprecated
WifiConfiguration in android.net has been deprecated
我很困惑,因为我在 C:\Users\{YOUR_ACCOUNT}\AppData\Local\Android\Sdk\sources\android-22\com\android\connectivitymanagertest
中看到了使用该方法访问 wifi 的 sdk 22 示例,但为什么它似乎已被弃用?
有什么方法可以替代已弃用的方法?
public boolean isWifiConnected() {
boolean isWifiConnected = false;
try {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo != null) {
isWifiConnected = networkInfo.getState() == CONNECTED;
}
Log.i(TAG, "wifi adapter is connected? " + isWifiConnected);
} catch (Exception ex) {
ex.printStackTrace();
}
return isWifiConnected;
}
public void removeNetwork() {
List<WifiConfiguration> wifiCfgList = wifiManager.getConfiguredNetworks();
if (wifiCfgList.size() > 0) {
for (WifiConfiguration item : wifiCfgList) {
if (item != null) {
wifiManager.removeNetwork(item.networkId);
wifiManager.saveConfiguration();
}
}
}
}
感谢指出。
已弃用的 classes 已替换为 ConnectivityManager
系统服务和 NetworkCallbacks
:https://developer.android.com/training/monitoring-device-state/connectivity-status-type
尽管官方代码示例显示了如何从 ConnectivityManager
获取 NetworkInfo
,但有一个突出显示的注释:
这是一个示例代码,说明您如何获取当前网络状态并随着时间的推移接收更新。这是我将在生产中使用的部分精简的解决方案。如果您将它与 RxJava 或 RxKotlin 连接,您可以创建一个可观察对象来保存网络状态,并在调用 NetworkCallback 的重写方法时进行更新。
关于 Java 的注意事项:public class 级变量被设为 public 只是为了简洁。相反,我会为它们创建一些 getter 来访问这些变量背后的值。
欢迎提问。
Java
class NetworkReachabilityService {
public NetworkType networkType;
public NetworkState networkState = NetworkState.Unavailable;
private ConnectivityManager connectivityManager;
private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
updateAvailability(connectivityManager.getNetworkCapabilities(network));
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
networkState = NetworkState.Losing;
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
networkState = NetworkState.Lost;
}
@Override
public void onUnavailable() {
super.onUnavailable();
networkState = NetworkState.Unavailable;
}
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
updateAvailability(networkCapabilities);
}
};
public NetworkReachabilityService(Context context) {
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
private void updateAvailability(NetworkCapabilities networkCapabilities) {
if (networkCapabilities == null) {
networkState = NetworkState.Unavailable;
return;
}
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
networkType = NetworkType.CELL;
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
networkType = NetworkType.WiFi;
}
networkState = NetworkState.Available;
}
public void resumeListeningNetworkChanges() {
pauseListeningNetworkChanges();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback);
} else {
connectivityManager.registerNetworkCallback(
new NetworkRequest.Builder().build(),
networkCallback
);
}
}
public void pauseListeningNetworkChanges() {
try {
connectivityManager.unregisterNetworkCallback(networkCallback);
} catch (IllegalArgumentException exception) {
// Usually happens only once if: "NetworkCallback was not registered"
}
}
private enum NetworkState {
Available, Unavailable, Connecting, Losing, Lost
}
private enum NetworkType {
WiFi, CELL, OTHER
}
}
科特林
sealed class NetworkState {
data class Available(val type: NetworkType) : NetworkState()
object Unavailable : NetworkState()
object Connecting : NetworkState()
object Losing : NetworkState()
object Lost : NetworkState()
}
sealed class NetworkType {
object WiFi : NetworkType()
object CELL : NetworkType()
object OTHER : NetworkType()
}
class NetworkReachabilityService private constructor(context: Context) {
private val connectivityManager: ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
// There are more functions to override!
override fun onLost(network: Network) {
super.onLost(network)
networkState = NetworkState.Lost
}
override fun onUnavailable() {
super.onUnavailable()
networkState = NetworkState.Unavailable
}
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
networkState = NetworkState.Losing
}
override fun onAvailable(network: Network) {
super.onAvailable(network)
updateAvailability(connectivityManager.getNetworkCapabilities(network))
}
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
updateAvailability(networkCapabilities)
}
}
var networkState: NetworkState = NetworkState.Unavailable
private set
private fun updateAvailability(networkCapabilities: NetworkCapabilities?) {
if (networkCapabilities == null) {
networkState = NetworkState.Unavailable
return
}
var networkType: NetworkType = NetworkType.OTHER
if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
networkType = NetworkType.CELL
}
if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) {
networkType = NetworkType.WiFi
}
networkState = NetworkState.Available(networkType)
}
fun pauseListeningNetworkChanges() {
try {
connectivityManager.unregisterNetworkCallback(networkCallback)
} catch (e: IllegalArgumentException) {
// Usually happens only once if: "NetworkCallback was not registered"
}
}
fun resumeListeningNetworkChanges() {
pauseListeningNetworkChanges()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback)
} else {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(),
networkCallback
)
}
}
}
要开始接收网络状态更新,请分别调用 resumeListeningNetworkChanges
和停止 pauseListeningNetworkChanges
。
更新:如何在已弃用的和新的之间切换 API
请注意,即使您使用此解决方案,您仍然会收到一条消息,表明您使用的特定代码已被弃用!它完全没问题,只要您提供一个可以在新 API 和旧的、已弃用的 API.
之间切换的实现,就不会被视为错误。这是一个近似解。由于新的 classes 是在 API 级别 29 中添加的,我们必须使用 Build.VERSION_CODES.Q
因为它是一个整数,其值为 29
.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Use new API here
} else {
// Use old API here
}