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

Caso seu app precise 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 o URI do nome de pacote do app, por exemplo, package:MY_APP_ID.

O envio da intent e do URI inicia o app Configurações e exibe as configurações de uso de dados do app. Em seguida, o usuário pode decidir se quer ativar os dados em segundo plano para o app. Antes de enviar essa intent, recomenda-se perguntar primeiro ao usuário se ele quer iniciar o app Configurações para 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, exibindo 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.