NetworkInfo已過時

今天編譯的時候發現,請求網絡前判斷設備是否聯網的方法提示警告,內容爲NetworkInfo過時
趕緊點開查看過時說明,發現NetworkInfo在API level 29中過時,ConnectivityManager中有許多返回值爲NetworkInfo的方法,自此一併不推薦使用了。
以前我們常用mConnectivityManager.getActiveNetworkInfo()獲取NetworkInfo,通過isConnected()判斷是否連通
查閱文檔顯示如下

@deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to
 *             learn about connectivity changes, or switch to use
 *             {@link ConnectivityManager#getNetworkCapabilities} or
 *             {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep
 *             in mind that while callbacks are guaranteed to be called for every event in order,
 *             synchronous calls have no such constraints, and as such it is unadvisable to use the
 *             synchronous methods inside the callbacks as they will often not offer a view of
 *             networking that is consistent (that is: they may return a past or a future state with
 *             respect to the event being processed by the callback). Instead, callers are advised
 *             to only use the arguments of the callbacks, possibly memorizing the specific bits of
 *             information they need to keep from one callback to another.

官方提到了兩個同步方法,和一個異步方法,官方警告說同步的方法會有更新不及時,反饋不及時的問題,無法保證多次調用的結果一致性。
但我主要爲了判斷瞬時網絡通斷,就使用返回NetworkCapabilities的getNetworkCapabilities

1)網絡狀態改變監聽:異步方法ConnectivityManager.NetworkCallback (NetWork)
2)網絡狀態獲取:同步方法
//獲取網絡屬性
public NetworkCapabilities getNetworkCapabilities (@Nullable Network network)
方法內部調用的是:mService.getNetworkCapabilities(network);
//獲取連接屬性
public LinkProperties getLinkProperties(int networkType) 
    public LinkProperties getLinkProperties(@Nullable Network network)
方法內部調用的是:mService.getLinkPropertiesForType(networkType);

//注意 上述兩個方法的Network是通過mConnectivityManager.getActiveNetwork()獲取的

官方推薦的替代方案中使用的NetworkCapabilities,是API 21增加的類,但API23中才增加了判斷的描述NET_CAPABILITY_VALIDATED,因此NetworkCapabilities最低支持Android 6.0版本.
實際使用時需要做版本判斷,項目如需兼容早期版本則無法完全摒除NetworkInfo
參考帖子了中對NetworkCapabilities的測試,發現其描述中有“VALIDATED”字段時,此網絡是真正可用的。

打印networkCapabilities.toString()

未聯網
networkCapabilities=null

移動4G流量
NetworkCapalbilities:[ Transports: CELLULAR Capabilities: SUPL&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED Unwanted:  LinkUpBandwidth>=51200Kbps LinkDnBandwidth>=102400Kbps Specifier: <1>]

wifi
5G熱點
NetworkCapalbilities:[ Transports: WIFI Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED Unwanted:  LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps SignalStrength: -46]
4G熱點
NetworkCapalbilities:[ Transports: WIFI Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps SignalStrength: -53]

本次只用了熱點wifi做測試,但已經看出來4G和5G有一些差別

結合參考文檔中測試的兩種情況
1)在不可上網的wifi下,可以看到也沒有VALIDATED的標記
在不可上網的wifi下,可以看到也沒有VALIDATED的標記
2)在需要認證的wifi下,可以看到相應區域沒有VALIDATED的標記
在需要認證的wifi下,可以看到相應區域沒有VALIDATED的標記
綜合上述信息,NetworkCapabilities的描述中有VALIDATED這個描述時,此網絡是真正可用的。那麼我們可以:

1)通過判斷這個標記是否存在來判斷網絡的連通性
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
2)通過字符串轉義抓取判斷
networkCapabilities.toString().indexOf("VALIDATED") > -1;

綜合以上情況修改網絡判斷代碼如下:

public static boolean isConnected() {
	ConnectivityManager mConnectivityManager = (ConnectivityManager) BaseApplication.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
	if(Build.VERSION.SDK_INT>=23) {
		//獲取網絡屬性
		NetworkCapabilities networkCapabilities = mConnectivityManager.getNetworkCapabilities(mConnectivityManager.getActiveNetwork());
		if (networkCapabilities != null) {
			LogUtil.i("Avalible","NetworkCapalbilities:"+networkCapabilities.toString());
			return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
		}
	}else {
		NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
		if (mNetworkInfo != null) {
			return mNetworkInfo.isConnected();
		}
	}
	return false;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章