Otimizar o uso de dados de rede

Durante a vida útil de um smartphone, o custo do plano de dados móveis pode facilmente exceder o custo do próprio dispositivo. No Android 7.0 (nível 24 da API) e mais recentes, os usuários podem ativar a Economia de dados para o dispositivo como um todo para otimizar o uso e consumir menos dados. Esse recurso é particularmente útil para roaming, perto do final do ciclo de faturamento ou para pacotes de dados pré-pagos pequenos.

Quando um usuário ativa a Economia de dados nas Configurações e o dispositivo está em uma rede limitada, o sistema bloqueia o uso de dados em segundo plano e avisa aos apps para reduzir o uso de dados no primeiro plano sempre que possível. Os usuários podem permitir que apps específicos usem dados limitados em segundo plano, mesmo quando a Economia de dados estiver ativada.

O Android 7.0 (nível 24 da API) estende a API ConnectivityManager para oferecer aos apps uma forma de recuperar as preferências da Economia de dados do usuário e monitorar as mudanças de preferências. É recomendado que os apps verifiquem se o usuário ativou a Economia de dados e tentem limitar o uso de dados em primeiro e segundo plano.

Verificar as preferências da Economia de dados

No Android 7.0 (nível 24 da API) ou versões mais recentes, os apps podem usar a API ConnectivityManager para determinar quais restrições de uso de dados serão aplicadas. O método getRestrictBackgroundStatus() retorna um dos seguintes valores:

RESTRICT_BACKGROUND_STATUS_DISABLED
A Economia de dados está desativada.
RESTRICT_BACKGROUND_STATUS_ENABLED
O usuário ativou a Economia de dados para este app. Os apps tentarão limitar o uso de dados em primeiro plano e gerenciar as restrições ao uso de dados em segundo plano.
RESTRICT_BACKGROUND_STATUS_WHITELISTED
O usuário ativou a Economia de dados, mas o app tem permissão para ignorá-la. Os apps ainda tentarão limitar o uso de dados em primeiro e segundo plano.

Limite o uso de dados sempre que o dispositivo estiver conectado a uma rede tarifada, mesmo que a "Economia de dados" esteja desativada ou o app tenha permissão para ignorá-la. O exemplo de código a seguir usa ConnectivityManager.isActiveNetworkMetered() e ConnectivityManager.getRestrictBackgroundStatus() para determinar o volume de dados que o app usa:

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

Observação: esse comportamento é diferente no Android TV. Em vez de bloquear o uso em segundo plano, o Android TV apenas o limita. Em primeiro plano, os aplicativos são limitados a 800 Kbps e, em segundo plano, a 10 Kbps. Use ConnectivityManager.isActiveNetworkMetered() para detectar quando limitar o uso de dados na TV.

Solicitar permissões de restrição de dados

Se o app precisar usar dados em segundo plano, ele poderá solicitar permissões de restrição de dados enviando uma intent Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS que contenha um URI com o nome de pacote do app, por exemplo, package:MY_APP_ID.

O envio da intent e do URI abre o app Configurações e exibe as configurações de uso de dados do app. O usuário pode decidir se quer ativar os dados em segundo plano para o app. Antes de enviar essa intent, é recomendável perguntar primeiro ao usuário se ele quer iniciar o app Configurações com o objetivo de ativar o uso de dados em segundo plano.

Monitorar mudanças nas preferências da Economia de dados

Apps podem monitorar mudanças nas preferências da Economia de dados criando um BroadcastReceiver para detectar ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED e registrar dinamicamente o receptor usando Context.registerReceiver(). Ao receber essa transmissão, o app precisará verificar se as novas preferências da Economia de dados afetam as permissões chamando ConnectivityManager.getRestrictBackgroundStatus().

Observação: o sistema só envia essa transmissão para apps que se registram dinamicamente para receber a transmissão deles usando Context.registerReceiver(). Os apps que se registrarem para receber a transmissão no manifesto não a receberão.

Testar com comandos do Android Debug Bridge

O Android Debug Bridge (adb) fornece alguns comandos que você pode usar para testar seu app nas condições da Economia de dados. Você pode verificar e configurar permissões de rede ou definir redes sem fio como limitadas para testar seu app em redes ilimitadas.

$ adb shell dumpsys netpolicy
Gera um relatório que inclui a configuração global atual de restrição da rede em segundo plano, os UIDs do pacote que podem ignorar a Economia de dados no momento e as permissões de outros pacotes conhecidos.
$ adb shell cmd netpolicy
Exibe uma lista completa de comandos do Gerenciador de políticas de rede (netpolicy).
$ adb shell cmd netpolicy set restrict-background <boolean>
Ativa ou desativa o modo de Economia de dados ao transmitir true ou false, respectivamente.
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
Adiciona o UID do pacote especificado à lista de permissões (whitelist) para permitir o uso de dados limitados em segundo plano.
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
Remove o UID do pacote especificado da lista de permissões (whitelist) para bloquear o uso de dados limitados em segundo plano enquanto a Economia de dados estiver ativada.
$ adb shell cmd netpolicy list wifi-networks
Lista todas as redes Wi-Fi, mostrando se elas são limitadas.
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
Define o Wi-Fi com o SSID especificado como limitado, o que permite simular uma rede limitada em uma rede ilimitada.