使用智慧型手機的期間,行動數據方案費用很容易超出裝置本身的費用。在 Android 7.0 (API 級別 24) 以上版本中,使用者可以啟用數據節省模式,為裝置進行最佳化,減少整體數據用量。這項功能特別適用於漫遊、帳單週期的尾聲,或是小型預付數據方案。
使用者在「設定」中啟用數據節省模式,且使用計量付費網路時,系統會封鎖背景數據使用,並通知應用程式在前景時也盡可能減少數據用量。即使啟用了數據節省模式,使用者還是可以允許特定應用程式使用背景計量付費數據用量。
Android 7.0 (API 級別 24) 會擴充 ConnectivityManager
API,透過擷取使用者的數據節省模式偏好設定,以及監控偏好設定變更的方式,來提供應用程式。讓應用程式查看使用者是否啟用了數據節省模式,並盡量限制前景和背景數據用量,會是相當不錯的做法。
查看數據節省模式偏好設定
在 Android 7.0 (API 級別 24) 以上版本中,應用程式可以使用 ConnectivityManager
API,決定要套用哪種數據用量限制。getRestrictBackgroundStatus()
方法會傳回下列其中一個值:
-
RESTRICT_BACKGROUND_STATUS_DISABLED
- 數據節省模式已停用。
-
RESTRICT_BACKGROUND_STATUS_ENABLED
- 使用者已針對這個應用程式啟用數據節省模式。應用程式應盡量減少前景數據用量,並妥善處理背景數據用量的限制。
-
RESTRICT_BACKGROUND_STATUS_WHITELISTED
- 使用者已啟用數據節省模式,但該應用程式不受此限。應用程式仍須盡量限制前景和背景的數據用量。
即使停用數據節省模式或應用程式不受此限,裝置使用計量付費網路時,仍會套用數據用量限制。以下程式碼範例說明如何使用 ConnectivityManager.isActiveNetworkMetered()
和 ConnectivityManager.getRestrictBackgroundStatus()
來判斷應用程式應使用多少數據:
Kotlin
(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply { // Checks if the device is on a metered network if (isActiveNetworkMetered) { // Checks user’s Data Saver settings. when (restrictBackgroundStatus) { RESTRICT_BACKGROUND_STATUS_ENABLED -> { // Background data usage is blocked for this app. Wherever possible, // the app should also use less data in the foreground. } RESTRICT_BACKGROUND_STATUS_WHITELISTED -> { // The app is allowed to bypass Data Saver. Nevertheless, wherever possible, // the app should use less data in the foreground and background. } RESTRICT_BACKGROUND_STATUS_DISABLED -> { // Data Saver is disabled. Since the device is connected to a // metered network, the app should use less data wherever possible. } } } else { // The device is not on a metered network. // Use data as required to perform syncs, downloads, and updates. } }
Java
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); // Checks if the device is on a metered network if (connMgr.isActiveNetworkMetered()) { // Checks user’s Data Saver settings. switch (connMgr.getRestrictBackgroundStatus()) { case RESTRICT_BACKGROUND_STATUS_ENABLED: // Background data usage is blocked for this app. Wherever possible, // the app should also use less data in the foreground. case RESTRICT_BACKGROUND_STATUS_WHITELISTED: // The app is allowed to bypass Data Saver. Nevertheless, wherever possible, // the app should use less data in the foreground and background. case RESTRICT_BACKGROUND_STATUS_DISABLED: // Data Saver is disabled. Since the device is connected to a // metered network, the app should use less data wherever possible. } } else { // The device is not on a metered network. // Use data as required to perform syncs, downloads, and updates. }
注意:在 Android TV 上的運作方式有所不同。Android TV 並不會禁止背景使用數據,只會執行節流。前景應用程式的限制為 800 Kbps,背景應用程式則為 10 Kbps。如要偵測何時應限制 Android TV 上的數據用量,可使用 ConnectivityManager.isActiveNetworkMetered()
。
要求數據限制權限
如果應用程式需要在背景使用數據,可以傳送 Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS
意圖,內容包含該應用程式套件名稱的 URI,藉此要求數據限制權限,例如:package:MY_APP_ID
。
傳送意圖和 URI 會啟動「設定」應用程式,並顯示應用程式的數據用量設定。使用者依此決定是否授權,讓應用程式使用背景數據。較為妥當的做法是在傳送意圖前,先詢問使用者是否要啟動「設定」。
監控數據節省模式的偏好設定變更情形
應用程式可以透過建立 BroadcastReceiver
來監聽 ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED
,並使用 Context.registerReceiver()
以動態方式註冊接收器,從而監控數據節省模式的偏好設定變更情形。收到這個廣播訊息時,應用程式應呼叫 ConnectivityManager.getRestrictBackgroundStatus()
來檢查新的數據節省模式偏好設定是否會影響自身的權限。
注意:廣播訊息只會傳送給使用 Context.registerReceiver()
進行動態註冊的應用程式。註冊要在資訊清單中接收這類廣播訊息的應用程式不會收到廣播訊息。
使用 Android Debug Bridge 指令進行測試
Android Debug Bridge (ADB) 會提供幾個指令,協助您在數據節省模式條件下測試應用程式。您可以檢查並設定網路權限,或將無線網路設為計量付費,以便在非計量付費網路中測試應用程式。
-
$ adb shell dumpsys netpolicy
- 產生報表,內容包括目前全球背景網路限制設定、目前不受數據節省模式影響的套件 UID,以及其他已知套件的網路權限。
-
$ adb shell cmd netpolicy
- 顯示「網路政策管理工具」(netpolicy) 完整指令清單。
-
$ adb shell cmd netpolicy set restrict-background <boolean>
- 在傳遞
true
或false
時,分別啟用或停用數據節省模式。 -
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
- 將指定套件 UID 加入許可清單 (
whitelist
),允許背景使用計量付費數據。 -
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
- 將指定套件 UID 從許可清單 (
whitelist
) 中移除,從而在啟用數據節省模式時,封鎖背景使用計量付費數據。 -
$ adb shell cmd netpolicy list wifi-networks
- 列出所有 Wi-Fi 網路,顯示是否為計量付費網路。
-
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
- 將含有指定 SSID 的 Wi-Fi 網路設為計量付費,這樣您就能在非計量付費網路上模擬計量付費網路。