Android 系統可讓應用程式瞭解網路連線的動態變化。請使用下列類別來追蹤及回應網路連線改變的情況:
ConnectivityManager
會向應用程式告知系統的連線狀態。Network
類別代表 裝置所連接的網路您可以使用Network
物件做為鍵,以透過ConnectivityManager
收集網路相關資訊,或繫結網路的通訊端。連上網路後 連線中斷,Network
物件即無法使用。即使之後使用裝置也沒問題 會重新連線到同一設備,新的Network
物件代表 Kubernetes 環境LinkProperties
物件 包含網路連結的相關資訊,例如 DNS 清單 伺服器、本機 IP 位址和網路路徑NetworkCapabilities
物件包含網路屬性的相關資訊,例如 以及網路支援的連線方式 (Wi-Fi、行動網路、藍牙)。 舉例來說,您可以查詢物件,以判斷網路是否 能夠傳送多媒體訊息、設有網頁認證入口,或為計量付費
如果應用程式希望在任何時間點都能取得即時連線狀態,只要呼叫 ConnectivityManager
方法即可得知可用的網路類型。對於偵錯以及偶爾檢閱
任一特定時間點的可用連線快照
不過,非同步的
ConnectivityManager
方法未向應用程式說明任何狀況
因此無法讓您更新使用者介面,他們也無法調整應用程式
根據網路連線中斷或網路功能的狀況
變更。
網路連線隨時可能改變,大多數應用程式都必須
裝置的最新網路狀態資訊。應用程式可以
向 ConnectivityManager
註冊回呼,讓系統在
使用者在乎的事情應用程式可透過回呼立即回應任何
導致相關網路能力變化,而不需改用昂貴的輪詢作業
以免錯過快速更新
使用 NetworkCallback
和其他來找出
連線狀態不需要任何特定權限,
不過,使用某些網路需具備特定權限。
適用對象
舉例來說,應用程式可能無法在某些受限制的網路下使用。繫結至
背景網路需要CHANGE_NETWORK_STATE
權限。還有
呼叫可能需要特定權限才能執行請參閱
來取得詳細資料。
取得即時狀態
Android 裝置可以同時保持多個網路連線。
如要取得目前網路狀態的資訊,請先取得
ConnectivityManager
的執行個體:
Kotlin
val connectivityManager = getSystemService(ConnectivityManager::class.java)
Java
ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);
接著,透過這個執行個體取得目前預設網路的參照 應用程式:
Kotlin
val currentNetwork = connectivityManager.getActiveNetwork()
Java
Network currentNetwork = connectivityManager.getActiveNetwork();
應用程式可透過對網路的參照,要求取得網路的相關資訊:
Kotlin
val caps = connectivityManager.getNetworkCapabilities(currentNetwork) val linkProperties = connectivityManager.getLinkProperties(currentNetwork)
Java
NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(currentNetwork); LinkProperties linkProperties = connectivityManager.getLinkProperties(currentNetwork);
如需更實用的功能,請註冊
NetworkCallback
。
如要進一步瞭解如何註冊網路回呼,請參見
監聽網路事件。
NetworkCapabilities 和 LinkProperties
NetworkCapabilities
和 LinkProperties
物件會提供
系統瞭解的網路屬性
LinkProperties
物件可取得路徑、連結位址、介面名稱、Proxy 資訊 (如果
和 DNS 伺服器對 LinkProperties
物件呼叫相關方法
擷取所需資訊
NetworkCapabilities
物件
封裝網路的「傳輸」及「功能」相關資訊。
傳輸是一種實體媒介的抽象層,而網路會在其上運作。常見的傳輸方式包括乙太網路、Wi-Fi 和行動裝置。
VPN 和點對點 Wi-Fi 也可以做為傳輸方式。
在 Android 裝置上,網路可以同時提供多種傳輸方式。範例
是同時支援 Wi-Fi 和行動網路的 VPNVPN 提供
Wi-Fi、行動裝置和 VPN 傳輸方式。要瞭解
如果有特定傳輸路徑,則請使用
NetworkCapabilities.hasTransport(int)
敬上
方法搭配其中一個 NetworkCapabilities.TRANSPORT_*
常數。
功能可描述網路的屬性,例如 MMS
、NOT_METERED
和 INTERNET
等功能。支援 MMS 功能的網路
以及接收多媒體訊息服務的訊息和網路
具備 NOT_METERED
功能的網路不會針對
使用者資料。應用程式可使用
NetworkCapabilities.hasCapability(int)
敬上
方法搭配其中一個 NetworkCapabilities.NET_CAPABILITY_*
常數。
最實用的 NET_CAPABILITY_*
常數包括:
NET_CAPABILITY_INTERNET
: 表示網路已設定完成 存取網際網路。這是關於設定的問題,而不是實際的 能力連線至公用伺服器舉例來說,網路可以設為 連上網際網路,但須透過網頁認證入口驗證身分。電信業者的行動網路通常具有
INTERNET
功能, 本機 P2P Wi-Fi 網路通常不會這麼做如需實際連線相關說明,請參閱NET_CAPABILITY_VALIDATED
。NET_CAPABILITY_NOT_METERED
: 表示網路並非計量付費網路 如果使用者對具體用量很敏感,則屬於「計量付費」 連線費用、數據用量限製或電池效能等問題 以負載平衡機制分配流量 即可降低應用程式發生效能問題的風險NET_CAPABILITY_NOT_VPN
: 表示網路並非虛擬私人網路。NET_CAPABILITY_VALIDATED
: 表示網路會提供 都會在探測器時連線至公開網際網路網路不受到監控的網路 或網路沒有提供網域名稱解析服務, 這項功能這是系統能判斷出最接近網路的網路資訊 雖然經過驗證的網路仍可存取 原則上,就算是按照 IP 進行篩選,還是在 造成連線速度過慢等問題NET_CAPABILITY_CAPTIVE_PORTAL
: 表示系統在探測網路時,網路有網頁認證入口。
系統還提供適用於更專門領域應用程式的其他功能。詳情請參閱
NetworkCapabilities.hasCapability(int)
。
網路的功能可能隨時變動。當系統偵測到網頁認證入口時,會顯示邀請使用者登入的通知。雖然這是
進行中,網路已具備 NET_CAPABILITY_INTERNET
NET_CAPABILITY_CAPTIVE_PORTAL
功能,但沒有
NET_CAPABILITY_VALIDATED
功能。
使用者採取行動並登入
進入網頁認證入口頁面後,裝置就能存取公開網際網路
而網路會取得 NET_CAPABILITY_VALIDATED
功能,並失去
NET_CAPABILITY_CAPTIVE_PORTAL
功能。
同樣地,網路的傳輸方式可能會以動態方式變動。
例如,VPN 可以自行重新設定
例如從行動網路改用 Wi-Fi
對基礎網路造成影響在此情況下,網路會失去 TRANSPORT_CELLULAR
移動和取得 TRANSPORT_WIFI
傳輸功能,同時保留
搭乘「TRANSPORT_VPN
」
監聽網路事件
如要得知網路事件,請將 NetworkCallback
類別與 ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback)
和 ConnectivityManager.registerNetworkCallback(NetworkCallback)
搭配使用。這兩種方法提供的用途不同。
所有 Android 應用程式都有由系統決定的預設網路。 系統通常會偏好使用非計量付費的網路 。
當應用程式發出網路要求時 (例如:
HttpsURLConnection
、
讓系統使用預設網路來滿足這項要求此外,應用程式也可以透過其他網路傳送流量。如需詳細資訊,請參閱「
網路。
在運作期間, 設為預設網路的網路可能隨時變更 應用程式的生命週期典型例子就是裝置的運作範圍 已知、使用中、非計量付費且速度比行動網路更快的 Wi-Fi 存取點。 裝置 會連線至這個存取點,並切換所有 轉移到新的 Wi-Fi 網路。
當新的網路成為預設網路時,應用程式開啟的所有新連線都會使用這個網路。一段時間後,上一個連線的所有剩餘連線 系統會強制終止預設網路如果應用程式必須 一旦預設網路有所變更,它就會註冊預設網路 回呼,如下所示:
Kotlin
connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network : Network) { Log.e(TAG, "The default network is now: " + network) } override fun onLost(network : Network) { Log.e(TAG, "The application no longer has a default network. The last default network was " + network) } override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) { Log.e(TAG, "The default network changed capabilities: " + networkCapabilities) } override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) { Log.e(TAG, "The default network changed link properties: " + linkProperties) } })
Java
connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { Log.e(TAG, "The default network is now: " + network); } @Override public void onLost(Network network) { Log.e(TAG, "The application no longer has a default network. The last default network was " + network); } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { Log.e(TAG, "The default network changed capabilities: " + networkCapabilities); } @Override public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) { Log.e(TAG, "The default network changed link properties: " + linkProperties); } });
當新網路成為預設網路時,應用程式會收到針對新網路的 onAvailable(Network)
呼叫。請實作 onCapabilitiesChanged(Network,NetworkCapabilities)
和/或 onLinkPropertiesChanged(Network,LinkProperties)
,以適當因應連線變更的狀況。
如果是向 registerDefaultNetworkCallback()
註冊的回呼,onLost()
代表網路已失去做為預設網路的狀態,可能會中斷連線。
雖然您可以瞭解預設網路目前採用的傳輸方式
查詢
NetworkCapabilities.hasTransport(int)
、
至於網路頻寬或計量付費範圍,這個 Proxy 的效能較差。您的應用程式
無法假設 Wi-Fi 一律為非計量付費方式
相較於行動裝置
請改用
NetworkCapabilities.getLinkDownstreamBandwidthKbps()
敬上
測量頻寬
NetworkCapabilites.hasCapability(int)
。
同時
NET_CAPABILITY_NOT_METERED
決定計量付費的引數詳情請參閱
NetworkCapabilities 和 LinkProperties。
根據預設,系統會透過應用程式的連線執行緒呼叫回呼方法,這類執行緒與 ConnectivityManager
所用的執行緒不同。如果您的
實作回呼需要進行較長的作業,
個別的背景工作執行緒
ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler)
。
如果您不再需要使用回呼,請呼叫 ConnectivityManager.unregisterNetworkCallback(NetworkCallback)
來取消註冊。建議您透過主要活動的 onPause()
取消註冊,特別是在 onResume()
中註冊回呼的情況。
其他網路
雖然預設網路是大多數應用程式唯一的相關網路,但部分應用程式
應用程式
可能會感興趣的其他可用網路想知道哪些應用程式
建立 NetworkRequest
需求並致電
ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback)
。
這套程序與監聽預設網路類似,然而
此版本可讓應用程式
應用程式會同時查看所有可用網路,因此呼叫
onLost(Network)
敬上
表示網路已中斷連線,不是預設連線
應用程式會建立 NetworkRequest
以通知 ConnectivityManager
要監聽哪種類型的網路。以下範例說明如何建立
NetworkRequest
:只對使用非計量付費網路的應用程式
連線:
Kotlin
val request = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build() connectivityManager.registerNetworkCallback(request, myNetworkCallback)
Java
NetworkRequest request = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build(); connectivityManager.registerNetworkCallback(request, myNetworkCallback);
這表示您的應用程式知道所有關於非計量付費的變更 連線至系統的網路
對於預設網路回呼,會有
registerNetworkCallback(NetworkRequest, NetworkCallback, Handler)
敬上
接受 Handler
,因此不會載入您的 Connectivity
執行緒
應用程式。
致電
ConnectivityManager.unregisterNetworkCallback(NetworkCallback)
敬上
當回呼不再相關時。一個應用程式可以同時註冊多個網路回呼。
為方便起見,NetworkRequest
物件包含多數應用程式需要的常用功能,包括:
編寫應用程式時,請檢查預設設定,確認是否與您的 如果想讓應用程式收到網路相關通知,請清除這些設定 不具備這些功能另一方面, 避免網路發生任何連線變更 使用者就無法與應用程式互動
舉例來說,如果您的應用程式需要傳送多媒體訊息,請在
NET_CAPABILITY_MMS
敬上
傳送至NetworkRequest
,以避免收到所有無法
傳送多媒體訊息。新增
TRANSPORT_WIFI_AWARE
敬上
(如果應用程式只想使用 P2P Wi-Fi 連線)。
「NET_CAPABILITY_INTERNET
」和
NET_CAPABILITY_VALIDATED
如果您想透過伺服器傳輸資料,可以使用
網際網路上
回呼順序範例
本節說明如果應用程式可以取得的回呼順序 在已連線的 裝置上,註冊預設回呼和一般回呼 具備行動連線能力。在此範例中,裝置會連線至有效的 Wi-Fi 存取點,然後再中斷連線。本範例也假設 裝置已啟用「行動數據一律開啟」設定。
時間軸如下:
當應用程式呼叫
registerNetworkCallback()
時,系統會立即回呼 接聽onAvailable()
、onNetworkCapabilitiesChanged()
和 行動網路的onLinkPropertiesChanged()
,因為只有行動網路 可以使用網路。如有其他可用網路,應用程式將 也會接收其他網路的回呼。
圖1. 呼叫registerNetworkCallback()
後的應用程式狀態。接著,應用程式會呼叫
registerDefaultNetworkCallback()
。預設網路 回呼會開始收到對onAvailable()
的呼叫,onNetworkCapabilitiesChanged()
,以及onLinkPropertiesChanged()
的 行動網路,因為行動網路為預設網路。如果 其他非預設網路啟用時,應用程式無法接收 對非預設網路的呼叫
圖2. 註冊預設網路後的應用程式狀態。稍後,裝置會連線至 (非計量付費) Wi-Fi 網路。一般網路回呼會收到針對 Wi-Fi 網路的
onAvailable()
、onNetworkCapabilitiesChanged()
和onLinkPropertiesChanged()
呼叫。
圖3.連線至非計量付費 Wi-Fi 網路後的應用程式狀態。這時 Wi-Fi 網路可能需要一些時間進行驗證。於 本例中,
onNetworkCapabilitiesChanged()
會呼叫一般網路 回呼不含NET_CAPABILITY_VALIDATED
功能。執行 短時間,系統就會呼叫onNetworkCapabilitiesChanged()
,而 新功能包括NET_CAPABILITY_VALIDATED
在多數情況下,驗證作業非常快速。Wi-Fi 網路通過驗證後,系統會偏好使用 Wi-Fi 網路而非行動網路 主要原因為非計量付費網路Wi-Fi 網路會成為預設網路,因此預設網路回呼會收到針對 Wi-Fi 網路的
onAvailable()
、onNetworkCapabilitiesChanged()
和onLinkPropertiesChanged()
呼叫。行動網路採用 而一般網路回呼會收到 行動網路的「onLosing()
」。由於本範例假設此裝置的行動數據一律處於開啟狀態,因此行動網路連線不會中斷。如果關閉這項設定 行動網路連線中斷時,以及一般網路回呼 會收到對
onLost()
的呼叫。
圖4. Wi-Fi 網路通過驗證後的應用程式狀態。後來,由於裝置離開連線範圍,因此 Wi-Fi 連線突然中斷。因為 Wi-Fi 連線中斷,一般網路回呼 收到 撥打
onLost()
連上 Wi-Fi。行動裝置是新的預設網路 預設網路回呼會收到對onAvailable()
的呼叫。onNetworkCapabilitiesChanged()
,以及onLinkPropertiesChanged()
的 行動網路。
圖5.Wi-Fi 網路連線中斷後的應用程式狀態。
如果「行動數據一律開啟」設定關閉,則裝置連上 Wi-Fi 時
中斷連線時,裝置會嘗試重新連上行動網路。圖片是
類似,但 onAvailable()
呼叫會有短暫延遲。
一般網路回呼也會接收對 onAvailable()
的呼叫。
onNetworkCapabilitiesChanged()
及onLinkPropertiesChanged()
,因為
還有行動裝置。
網路資料傳輸的使用限制
能透過網路回呼看到網路,不代表應用程式可以
透過網路傳輸資料部分網路不提供網際網路
且部分網路可能會
具有特殊權限的應用程式如要檢查網際網路連線,請參閱
NET_CAPABILITY_INTERNET
敬上
和
NET_CAPABILITY_VALIDATED
。
此外,使用背景網路也必須通過權限檢查。如果您的應用程式
想要使用背景網路,需要
CHANGE_NETWORK_STATE
敬上
權限。
具備這項權限的應用程式可讓系統嘗試
啟動未啟用的網路,例如行動網路
裝置連線 Wi-Fi 網路時。這類應用程式呼叫
ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback)
敬上
以及要在網路啟動時呼叫的 NetworkCallback