Otimizar o uso de dados de rede

Durante a vida útil de um smartphone, o custo do plano de dados da rede celular pode facilmente exceder o custo do próprio dispositivo. A partir do Android 7.0 (nível de API 24), 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 um pacote de dados pré-pago pequeno.

Quando um usuário ativa a Economia de dados em Configurações e o dispositivo está em uma rede tarifada, 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 colocar apps específicos na lista de permissões para que eles possam usar dados tarifados em segundo plano, mesmo com a Economia de dados ativada.

O Android 7.0 (nível de API 24) estende a API ConnectivityManager para oferecer aos apps uma forma de recuperar as preferências do usuário da Economia de Dados do usuário e monitorar as mudanças dessas preferências. Como prática recomendada, os apps precisam verificar se o usuário ativou a Economia de dados e tentar limitar o uso de dados em primeiro e segundo plano.

Verificar as preferências da Economia de dados

No Android 7.0 (API de nível 24), os apps podem usar a API ConnectivityManager para determinar as restrições de uso de dados que 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 está na lista de permissões. Os apps ainda tentarão limitar o uso de dados em primeiro e segundo plano.

É prática recomendada limitar o uso de dados sempre que o dispositivo estiver conectado a uma rede tarifada, mesmo que a Economia de dados esteja desativada e o app esteja na lista de permissões. A amostra de código a seguir usa ConnectivityManager.isActiveNetworkMetered() e ConnectivityManager.getRestrictBackgroundStatus() para determinar o volume de dados que o app precisa usar:

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

Solicitar permissão para colocar na lista de permissões

Caso seu app precise usar dados em segundo plano, ele poderá solicitar inclusão na lista de permissões enviando um intent Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS que contenha o URI no nome de pacote do app, por exemplo, package:MY_APP_ID.

O envio do intent e do URI abre o app Configurações e exibe as configurações de uso de dados do seu app. Assim, o usuário pode decidir se ativará os dados em segundo plano para o app. Antes de enviar o intent, recomenda-se 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 alterações nas preferências de Economia de dados

Apps podem monitorar alterações nas preferências da Economia de dados criando um BroadcastReceiver para escutar ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED e registrar dinamicamente o destinatário em 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 elas com 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 tarifadas para testar seu app em redes não tarifadas.

$ adb shell dumpsys netpolicy
Gera um relatório que inclui a configuração de restrição atual da rede de segundo plano global, os UIDs do pacote em lista de permissões e as permissões de rede 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 passar true ou false, respectivamente.
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
Adiciona o UID do pacote especificado à lista de permissões para permitir o uso de dados de segundo plano tarifados.
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
Remove o UID do pacote especificado da lista de permissões para bloquear o uso de dados de segundo plano tarifados enquanto a Economia de dados está ativada.
$ adb shell cmd netpolicy list wifi-networks
Lista todas as redes Wi-Fi, exibindo se elas são tarifadas.
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
Define o Wi-Fi com o SSID especificado como tarifado, o que permite simular uma rede tarifada em uma rede não tarifada.