Оптимизация использования сетевых данных

В течение срока службы смартфона стоимость тарифного плана сотовой связи может легко превысить стоимость самого устройства. В Android 7.0 (уровень API 24) и более поздних версиях пользователи могут включить функцию экономии данных на уровне всего устройства, чтобы оптимизировать использование данных своего устройства и использовать меньше данных. Эта возможность особенно полезна в роуминге, ближе к концу расчетного цикла или для небольшого пакета данных по предоплате.

Когда пользователь включает функцию «Экономия данных» в настройках и устройство находится в сети с лимитным трафиком, система блокирует использование фоновых данных и сигнализирует приложениям, чтобы они использовали меньше данных на переднем плане, где это возможно. Пользователи могут разрешить определенным приложениям использовать измеренное использование данных в фоновом режиме, даже если включена функция экономии трафика.

Android 7.0 (уровень API 24) расширяет API ConnectivityManager , предоставляя приложениям возможность получать настройки экономии данных пользователя и отслеживать изменения настроек . Хорошей практикой считается, когда приложения проверяют, включил ли пользователь функцию экономии данных, и стараются ограничить использование данных переднего и фонового плана.

Проверьте настройки экономии трафика

В Android 7.0 (уровень API 24) и более поздних версиях приложения могут использовать API ConnectivityManager , чтобы определить, какие ограничения на использование данных применяются. Метод getRestrictBackgroundStatus() возвращает одно из следующих значений:

RESTRICT_BACKGROUND_STATUS_DISABLED
Экономия данных отключена.
RESTRICT_BACKGROUND_STATUS_ENABLED
Пользователь включил экономию данных для этого приложения. Приложения должны стараться ограничивать использование данных на переднем плане и корректно обрабатывать ограничения на использование данных в фоновом режиме.
RESTRICT_BACKGROUND_STATUS_WHITELISTED
Пользователь включил функцию экономии трафика, но приложению разрешено ее обходить. Приложениям по-прежнему следует стараться ограничивать использование данных переднего и фонового плана.

Ограничивайте использование данных всякий раз, когда устройство подключено к сети с лимитным трафиком, даже если экономия данных отключена или приложению разрешено обходить ее. В следующем примере кода используются ConnectivityManager.isActiveNetworkMetered() и ConnectivityManager.getRestrictBackgroundStatus() , чтобы определить, какой объем данных должно использовать приложение:

Котлин

(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.
    }
}

Ява

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 Кбит/с, а в фоновом режиме — до 10 Кбит/с. Используйте 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 пакетов, которым в данный момент разрешено обходить Data Saver, а также сетевые разрешения других известных пакетов.
$ 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
Устанавливает Wi-Fi с указанным SSID как лимитированный, что позволяет имитировать лимитную сеть в сети без лимита.