Optymalizowanie wykorzystania transmisji danych w sieci

Z czasem użytkowania smartfona koszt abonamentu na komórkową transmisję danych może łatwo przekroczyć koszt samego urządzenia. Na Androidzie 7.0 (poziom interfejsu API 24) i nowszych użytkownicy mogą włączyć Oszczędzanie danych na całym urządzeniu, aby zoptymalizować wykorzystanie danych i wykorzystać mniej danych. Ta możliwość jest szczególnie przydatna w przypadku roamingu, pod koniec cyklu rozliczeniowego lub w przypadku małego przedpłaconego pakietu danych.

Gdy użytkownik włączy Oszczędzanie danych w Ustawieniach, a urządzenie korzysta z sieci z pomiarem użycia danych, system zablokuje użycie danych w tle i sygnalizuje aplikacjom, że w miarę możliwości zmniejszają ilość danych na pierwszym planie. Użytkownicy mogą zezwolić określonym aplikacjom na korzystanie z transmisji danych z pomiarem użycia danych w tle nawet wtedy, gdy Oszczędzanie danych jest włączone.

Android 7.0 (poziom interfejsu API 24) rozszerza interfejs ConnectivityManager API, aby zapewnić aplikacjom możliwość pobierania ustawień Oszczędzania danych użytkownika i monitorowania ich zmian. Dobrym pomysłem jest sprawdzenie przez aplikacje, czy użytkownik włączył Oszczędzanie danych, oraz ograniczenie wykorzystania danych na pierwszym planie i w tle.

Sprawdzanie ustawień oszczędzania danych

Na Androidzie 7.0 (poziom interfejsu API 24) i nowszych aplikacje mogą używać interfejsu ConnectivityManager API do określenia, jakie ograniczenia użycia danych są stosowane. Metoda getRestrictBackgroundStatus() zwraca jedną z tych wartości:

RESTRICT_BACKGROUND_STATUS_DISABLED
Oszczędzanie danych jest wyłączone.
RESTRICT_BACKGROUND_STATUS_ENABLED
Użytkownik włączył Oszczędzanie danych w tej aplikacji. Aplikacje powinny starać się ograniczać użycie danych na pierwszym planie i łatwo radzić sobie z ograniczeniami dotyczącymi użycia danych w tle.
RESTRICT_BACKGROUND_STATUS_WHITELISTED
Użytkownik włączył Oszczędzanie danych, ale aplikacja może je pominąć. Aplikacje nadal powinny starać się ograniczać ilość danych na pierwszym planie i w tle.

Ogranicz użycie danych, gdy urządzenie jest połączone z siecią z pomiarem użycia danych, nawet jeśli Oszczędzanie danych jest wyłączone lub aplikacja może je omijać. W tym przykładowym kodzie są używane ConnectivityManager.isActiveNetworkMetered() i ConnectivityManager.getRestrictBackgroundStatus(), które określają, ile danych powinna wykorzystywać aplikacja:

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

Uwaga: w Androidzie TV działa to inaczej. Zamiast blokować użycie w tle, Android TV tylko je ogranicza. Działanie aplikacji na pierwszym planie jest ograniczone do 800 kb/s, a w tle – do 10 kb/s. Użyj ConnectivityManager.isActiveNetworkMetered(), aby wykryć, kiedy należy ograniczyć użycie danych na telewizorze.

Prośba o ograniczenie dostępu do danych

Jeśli aplikacja musi używać danych w tle, może poprosić o uprawnienia do ograniczania dostępu do danych, wysyłając intencję Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS zawierającą identyfikator URI nazwy pakietu aplikacji, np. package:MY_APP_ID.

Wysłanie intencji i identyfikatora URI uruchamia aplikację Settings (Ustawienia) i wyświetla ustawienia użycia danych przez aplikację. Użytkownik może wtedy zdecydować, czy włączyć dane w tle dla aplikacji. Zanim wyślesz tę intencję, warto najpierw zapytać użytkownika, czy chce uruchomić aplikację Ustawienia, aby włączyć użycie danych w tle.

Monitorowanie zmian w ustawieniach oszczędzania danych

Aplikacje mogą monitorować zmiany w ustawieniach Oszczędzania danych, tworząc BroadcastReceiver, który nasłuchuje dźwięku ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED, i dynamicznie rejestrując odbiorcę za pomocą Context.registerReceiver(). Gdy aplikacja otrzyma tę transmisję, powinna sprawdzić, czy nowe ustawienia Oszczędzania danych wpływają na jej uprawnienia, wywołując metodę ConnectivityManager.getRestrictBackgroundStatus().

Uwaga: system wysyła tę transmisję tylko do aplikacji, które dynamicznie rejestrują się na potrzeby usługi Context.registerReceiver(). Aplikacje, które zarejestrowały się, aby otrzymywać tę transmisję w pliku manifestu, nie będą ich otrzymywać.

Testowanie za pomocą poleceń Android Debug Bridge

Android Debug Bridge (ADB) udostępnia kilka poleceń, których możesz użyć, aby przetestować aplikację w warunkach Oszczędzania danych. Aby przetestować aplikację w sieciach bez pomiaru, możesz sprawdzić i skonfigurować uprawnienia do sieci lub ustawić sieci bezprzewodowe jako z pomiarem.

$ adb shell dumpsys netpolicy
Generuje raport zawierający bieżące ustawienie globalnych ograniczeń sieci w tle, identyfikatory UID pakietów, które obecnie mogą pomijać Oszczędzanie danych, oraz uprawnienia sieciowe innych znanych pakietów.
$ adb shell cmd netpolicy
Wyświetla pełną listę poleceń menedżera zasad sieciowych (netpolicy).
$ adb shell cmd netpolicy set restrict-background <boolean>
Włącza lub wyłącza tryb Oszczędzania danych podczas przesyłania odpowiednio wartości true lub false.
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
Dodaje określony identyfikator UID pakietu do listy dozwolonych (whitelist), aby umożliwić użycie danych z pomiarem w tle.
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
Usuwa określony identyfikator UID pakietu z listy dozwolonych (whitelist), aby blokować użycie danych z pomiarem w tle przy włączonym Oszczędzaniu danych.
$ adb shell cmd netpolicy list wifi-networks
Wyświetla listę wszystkich sieci Wi-Fi i pokazuje, czy są one z pomiarem.
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
Ustawia Wi-Fi o określonym identyfikatorze SSID jako z pomiarem, co pozwala symulować sieć z pomiarem użycia danych w sieci bez pomiaru.