Cómo optimizar el uso de datos de red

Durante la vida útil de un smartphone, el costo de un plan de datos móviles puede superar fácilmente el costo del propio dispositivo. Con Android 7.0 (nivel de API 24) y versiones posteriores, los usuarios pueden habilitar el Ahorro de datos en todo el dispositivo para optimizar el uso de datos y consumir menos. Esta función es particularmente útil cuando se usa el roaming, cerca del final del ciclo de facturación, o bien para un pequeño paquete de datos prepago.

Cuando un usuario habilita Ahorro de datos en la Configuración y el dispositivo está conectado a una red de uso medido, el sistema bloquea el uso de datos en segundo plano y les indica a las apps que usen menos datos en primer plano siempre que sea posible. Los usuarios pueden habilitar apps específicas para que usen datos medidos en segundo plano, incluso cuando está activado el Ahorro de datos.

Android 7.0 (nivel de API 24) extiende la API de ConnectivityManager para que las apps puedan recuperar las preferencias del Ahorro de datos del usuario y controlar los cambios en ellas. Se considera una práctica recomendada que las apps verifiquen si el usuario habilitó el Ahorro de datos y hagan todo lo posible por limitar el uso de datos en primer y segundo plano.

Cómo verificar las preferencias del Ahorro de datos

En Android 7.0 (nivel de API 24) y versiones posteriores, las apps pueden usar la API de ConnectivityManager a fin de determinar qué restricciones de uso de datos se aplican. El método getRestrictBackgroundStatus() muestra uno de los siguientes valores:

RESTRICT_BACKGROUND_STATUS_DISABLED
El Ahorro de datos está inhabilitado.
RESTRICT_BACKGROUND_STATUS_ENABLED
El usuario habilitó Ahorro de datos para esta app. Las apps deberían hacer todo lo posible por limitar el uso de datos en primer plano y procesar de manera fluida las restricciones de uso de datos en segundo plano.
RESTRICT_BACKGROUND_STATUS_WHITELISTED
El usuario habilitó Ahorro de datos, pero la app tiene permiso para omitirlo. Las apps aún deben hacer lo posible por reducir el uso de datos en primer y segundo plano.

Limita el uso de datos siempre que el dispositivo esté conectado a una red de uso medido, incluso si el Ahorro de datos está inhabilitado o la app tiene permiso para omitirlo. En el siguiente código de muestra se usan ConnectivityManager.isActiveNetworkMetered() y ConnectivityManager.getRestrictBackgroundStatus() para determinar la cantidad de datos que debe utilizar la app:

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

Nota: Este comportamiento es diferente en Android TV. En lugar de bloquear el uso en segundo plano, Android TV solo lo limita. Cuando está en primer plano, las aplicaciones se limitan a 800 kbps y, en segundo plano, se limitan a 10 kbps. Usa ConnectivityManager.isActiveNetworkMetered() para detectar cuando se limita el uso de datos en la TV.

Cómo solicitar permisos de restricción de datos

Si la app necesita utilizar datos en segundo plano, esta puede solicitar permisos de restricción de datos mediante el envío de un intent Settings.ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS que contenga un URI del nombre de paquete de la app, como package:MY_APP_ID.

Cuando se envían el intent y el URI, se inicia la app de Configuración y se muestra la configuración del uso de datos de tu app. Luego, el usuario puede decidir si quiere habilitar los datos en segundo plano para tu app. Antes de enviar este intent, consúltale al usuario si desea iniciar la app de Configuración con el objetivo de habilitar el uso de datos en segundo plano.

Cómo supervisar los cambios en las preferencias del Ahorro de datos

Las apps pueden controlar los cambios en las preferencias del Ahorro de datos creando un BroadcastReceiver para escuchar a ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED y registrando de forma dinámica el receptor con Context.registerReceiver(). Cuando una app recibe esta transmisión, debe verificar si las nuevas preferencias del Ahorro de datos afectan los permisos. Para ello, debe invocar a ConnectivityManager.getRestrictBackgroundStatus().

Nota: El sistema solo envía esta transmisión a las apps que se registran de forma dinámica con Context.registerReceiver(). Las apps que están registradas para recibir esta transmisión en su manifiesto no la recibirán.

Cómo probar tu app con los comandos de Android Debug Bridge

Android Debug Bridge (ADB) proporciona algunos comandos que puedes usar para probar tu app cuando se activa Ahorro de datos. Puedes verificar y configurar los permisos de red o establecer redes inalámbricas de uso medido a fin de probar tu app en redes de uso no medido.

$ adb shell dumpsys netpolicy
Genera un informe en el que se incluyen la configuración global actual de restricciones de red en segundo plano, los UID de paquetes habilitados para omitir Ahorro de datos y los permisos de red de otros paquetes conocidos.
$ adb shell cmd netpolicy
Muestra una lista completa de los comandos del Administrador de políticas de red (netpolicy).
$ adb shell cmd netpolicy set restrict-background <boolean>
Habilita o inhabilita el modo Ahorro de datos cuando se pasan los valores true o false, respectivamente.
$ adb shell cmd netpolicy add restrict-background-whitelist <UID>
Agrega el UID del paquete determinado a la lista de entidades permitidas (whitelist) para habilitar el uso medido de datos en segundo plano.
$ adb shell cmd netpolicy remove restrict-background-whitelist <UID>
Quita el UID del paquete determinado de la lista de entidades permitidas (whitelist) para bloquear el uso medido de datos en segundo plano mientras Ahorro de datos está habilitado.
$ adb shell cmd netpolicy list wifi-networks
Enumera todas las redes Wi-Fi y especifica si son de uso medido o no.
$ adb shell cmd netpolicy set metered-network <WIFI_SSID> true
Establece la conexión Wi-Fi con el SSID especificado como de uso medido, lo que te permite simular una red de uso medido en una que no lo es.