Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Compatibilidad con actualizaciones dentro de la app

Mantener tu app actualizada en los dispositivos de los usuarios permite que ellos prueben nuevas funciones y aprovechen las mejoras de rendimiento y las correcciones de errores. Aunque algunos usuarios habilitan las actualizaciones en segundo plano para cuando su dispositivo tiene una conexión no medida, es posible que otros necesiten recibir recordatorios de las actualizaciones disponibles. Las actualizaciones dentro de la app son una función de la biblioteca de Play Core que presenta un nuevo flujo de solicitudes para pedir a los usuarios activos que actualicen tu app.

Las actualizaciones dentro de la app solo funcionan con dispositivos que ejecutan Android 5.0 (API nivel 21) o versiones posteriores y requieren que uses la biblioteca de Play Core 1.5.0 o versiones posteriores. Si se cumplen esos requisitos, tu aplicación puede admitir la siguiente UX para actualizaciones dentro de la app:

  • Flexible: Una experiencia del usuario que proporciona descargas e instalaciones en segundo plano con supervisión fluida del estado. Esta UX es apropiada cuando es aceptable que el usuario use la app mientras descarga la actualización. Por ejemplo, deseas instar a los usuarios a que prueben una nueva característica que no es imprescindible para la funcionalidad principal de tu app.

    Figura 1: Ejemplo de un flujo de actualización flexible

  • Inmediata: Una experiencia del usuario en pantalla completa que requiere que el usuario actualice y reinicie la aplicación para poder seguir usándola. Esta UX es ideal en los casos en que la actualización es crítica para el uso continuado de la app. Después de que el usuario acepta la actualización inmediata, Google Play maneja la instalación de la actualización y el reinicio de la app.

    Figura 2: Ejemplo de un flujo de actualización inmediata

En esta página, se muestra cómo usar la biblioteca de Play Core para solicitar y realizar una actualización flexible o inmediata dentro de la app.

Cómo comprobar la disponibilidad de actualizaciones

Antes de solicitarle al usuario que acepte una actualización para tu app, debes verificar que esa actualización esté disponible. Usa AppUpdateManager, como se muestra a continuación, para buscar la actualización:

Kotlin

    // Creates instance of the manager.
    val appUpdateManager = AppUpdateManagerFactory.create(context)

    // Returns an intent object that you use to check for an update.
    val appUpdateInfoTask = appUpdateManager.appUpdateInfo

    // Checks that the platform will allow the specified type of update.
    appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
        if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
            // For a flexible update, use AppUpdateType.FLEXIBLE
            && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
        ) {
            // Request the update.
        }
    }
    

Java

    // Creates instance of the manager.
    AppUpdateManager appUpdateManager = AppUpdateManagerFactory.create(context);

    // Returns an intent object that you use to check for an update.
    Task<AppUpdateInfo> appUpdateInfoTask = appUpdateManager.getAppUpdateInfo();

    // Checks that the platform will allow the specified type of update.
    appUpdateInfoTask.addOnSuccessListener(appUpdateInfo -> {
        if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
              // For a flexible update, use AppUpdateType.FLEXIBLE
              && appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
                  // Request the update.
        }
    });
    

El resultado contiene el estado de disponibilidad de la actualización. Si hay una actualización disponible y está permitida, la AppUpdateInfo que se muestra también contiene un intent para iniciar la actualización. Consulta la siguiente sección para saber cómo iniciar la actualización.

Si ya hay una actualización en curso dentro de la app, el resultado también informará el estado de esa actualización.

Cómo iniciar una actualización

Después de verificar que es posible actualizar la app, puedes solicitar la actualización usando AppUpdateManager.startUpdateFlowForResult(), como se muestra a continuación. Sin embargo, para evitar que los usuarios se cansen o se molesten, debes tener en cuenta la frecuencia con la que solicitas actualizaciones. Es decir, debes limitar la solicitud de actualizaciones dentro de la app solo a los cambios que son importantes para la funcionalidad de la app.

Kotlin

    appUpdateManager.startUpdateFlowForResult(
        // Pass the intent that is returned by 'getAppUpdateInfo()'.
        appUpdateInfo,
        // Or 'AppUpdateType.FLEXIBLE' for flexible updates.
        AppUpdateType.IMMEDIATE,
        // The current activity making the update request.
        this,
        // Include a request code to later monitor this update request.
        MY_REQUEST_CODE)
    

Java

    appUpdateManager.startUpdateFlowForResult(
        // Pass the intent that is returned by 'getAppUpdateInfo()'.
        appUpdateInfo,
        // Or 'AppUpdateType.FLEXIBLE' for flexible updates.
        AppUpdateType.IMMEDIATE,
        // The current activity making the update request.
        this,
        // Include a request code to later monitor this update request.
        MY_REQUEST_CODE);
    

Cada instancia de AppUpdateInfo se puede usar para iniciar una actualización solo una vez. Para volver a intentar realizar la actualización en caso de error, debes solicitar otra AppUpdateInfo y verificar nuevamente que la actualización está disponible y se permite.

El tipo de actualización que solicitas determina los próximos pasos que deberás realizar. Para obtener más información, consulta las secciones Cómo manejar una actualización inmediata o Cómo manejar una actualización flexible.

Cómo obtener una devolución de llamada sobre el estado de la actualización

Después de iniciar una actualización, puedes usar una devolución de llamada onActivityResult() para manejar un error o una cancelación de la actualización, como se muestra a continuación.

Kotlin

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        if (requestCode == MY_REQUEST_CODE) {
            if (resultCode != RESULT_OK) {
                log("Update flow failed! Result code: $resultCode")
                // If the update is cancelled or fails,
                // you can request to start the update again.
            }
        }
    }
    

Java

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == MY_REQUEST_CODE) {
        if (resultCode != RESULT_OK) {
          log("Update flow failed! Result code: " + resultCode);
          // If the update is cancelled or fails,
          // you can request to start the update again.
        }
      }
    }
    

A continuación, se describen los diferentes valores que puedes recibir de la devolución de llamada onActivityResult():

  • RESULT_OK: El usuario aceptó la actualización. En el caso de las actualizaciones inmediatas, es posible que no recibas esta devolución de llamada porque probablemente Google Play ya habrá completado la actualización para cuando tu app recupere el control.
  • RESULT_CANCELED: El usuario rechazó o canceló la actualización.
  • ActivityResult.RESULT_IN_APP_UPDATE_FAILED: Otro error impidió que el usuario proporcionara el consentimiento o que la actualización continuara.

Cómo manejar una actualización flexible

Cuando inicias una actualización flexible, el usuario primero ve un diálogo en el que se solicita su consentimiento. Si el usuario da el consentimiento, la descarga comienza en segundo plano y el usuario puede seguir interactuando con la app. Esta sección describe cómo supervisar y completar una actualización flexible dentro de la app.

Cómo supervisar el estado de una actualización flexible

Cuando un usuario acepta una actualización flexible, Google Play comienza a descargar la actualización en segundo plano. Una vez que empieza la descarga, tu app necesita supervisar el estado de la actualización para saber cuándo se puede instalar la actualización y mostrar el progreso en la IU de tu app.

Puedes supervisar el estado de una actualización en curso registrando un objeto de escucha para instalar actualizaciones de estado.

Kotlin

    // Create a listener to track request state updates.
    val listener = { state ->
        // Show module progress, log state, or install the update.
    }

    // Before starting an update, register a listener for updates.
    appUpdateManager.registerListener(listener)

    // Start an update.

    // When status updates are no longer needed, unregister the listener.
    appUpdateManager.unregisterListener(listener)
    

Java

    // Create a listener to track request state updates.
    InstallStateUpdatedListener listener = state -> {
        // Show module progress, log state, or install the update.
      };

    // Before starting an update, register a listener for updates.
    appUpdateManager.registerListener(listener);

    // Start an update.

    // When status updates are no longer needed, unregister the listener.
    appUpdateManager.unregisterListener(listener);
    

Cómo instalar una actualización flexible

Si supervisas el estado de la actualización flexible y detectas el estado InstallStatus.DOWNLOADED, debes reiniciar la app para instalar la actualización.

A diferencia de lo que ocurre con las actualizaciones inmediatas, en este caso Google Play no activa el reinicio de una app. Eso se debe a que, durante una actualización flexible, el usuario tiene la expectativa de seguir usando la aplicación hasta que decida que desea instalar la actualización.

Por lo tanto, te recomendamos proporcionar una notificación (o alguna otra indicación de la IU) para informar al usuario que la instalación finalizó y solicitar su confirmación antes de reiniciar la app.

Por ejemplo, puedes implementar una barra de notificaciones con Material Design para solicitar confirmación al usuario antes de reiniciar la app, como se muestra en la figura 1.

En el siguiente ejemplo de código, se muestra una notificación de la barra de notificaciones que ve el usuario tras la descarga de una actualización flexible.

Kotlin

    override fun onStateUpdate(state: InstallState) {
        if (state.installStatus() == InstallStatus.DOWNLOADED) {
            // After the update is downloaded, show a notification
            // and request user confirmation to restart the app.
            popupSnackbarForCompleteUpdate()
        }
        ...
    }

    /* Displays the snackbar notification and call to action. */
    fun popupSnackbarForCompleteUpdate() {
        Snackbar.make(
            findViewById(R.id.activity_main_layout),
            "An update has just been downloaded.",
            Snackbar.LENGTH_INDEFINITE
        ).apply {
            setAction("RESTART") { appUpdateManager.completeUpdate() }
            setActionTextColor(resources.getColor(R.color.snackbar_action_text_color))
            show()
        }
    }
    

Java

    @Override
    public void onStateUpdate(InstallState state) {
      if (state.installStatus() == InstallStatus.DOWNLOADED) {
        // After the update is downloaded, show a notification
        // and request user confirmation to restart the app.
        popupSnackbarForCompleteUpdate();
      }
      ...
    }

    /* Displays the snackbar notification and call to action. */
    private void popupSnackbarForCompleteUpdate() {
      Snackbar snackbar =
          Snackbar.make(
              findViewById(R.id.activity_main_layout),
              "An update has just been downloaded.",
              Snackbar.LENGTH_INDEFINITE);
      snackbar.setAction("RESTART", view -> appUpdateManager.completeUpdate());
      snackbar.setActionTextColor(
          getResources().getColor(R.color.snackbar_action_text_color));
      snackbar.show();
    }
    

Cuando llamas a appUpdateManager.completeUpdate() en primer plano, la plataforma muestra una IU en pantalla completa que reinicia la app en segundo plano. Una vez que la plataforma instala la actualización, la app se reinicia en su actividad principal.

Si, en cambio, llamas a appUpdateManager.completeUpdate() en segundo plano, la actualización se instala de manera silenciosa sin ocultar la IU del dispositivo.

Cuando el usuario lleva tu app al primer plano, es recomendable que verifiques que la aplicación no tenga una actualización pendiente. Si tu app tiene una actualización en el estado DOWNLOADED, muestra la notificación para solicitar que el usuario la instale, como se muestra a continuación. De lo contrario, los datos de la actualización seguirán ocupando el almacenamiento del dispositivo del usuario.

Kotlin

    // Checks that the update is not stalled during 'onResume()'.
    // However, you should execute this check at all app entry points.
    override fun onResume() {
        super.onResume()

        appUpdateManager
            .appUpdateInfo
            .addOnSuccessListener { appUpdateInfo ->
                ...
                // If the update is downloaded but not installed,
                // notify the user to complete the update.
                if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                    popupSnackbarForCompleteUpdate()
                }
            }
    }
    

Java

    // Checks that the update is not stalled during 'onResume()'.
    // However, you should execute this check at all app entry points.
    @Override
    protected void onResume() {
      super.onResume();

      appUpdateManager
          .getAppUpdateInfo()
          .addOnSuccessListener(appUpdateInfo -> {
                  ...
                  // If the update is downloaded but not installed,
                  // notify the user to complete the update.
                  if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
                      popupSnackbarForCompleteUpdate();
                  }
              });
    }
    

Cómo manejar una actualización inmediata

Si realizas una actualización inmediata y el usuario da su consentimiento para instalarla, Google Play mostrará el progreso durante toda la actualización en la parte superior de la IU de tu app. Durante este proceso, si el usuario cierra la app, la actualización debería continuar descargándose e instalándose en segundo plano sin que se requiera una nueva confirmación del usuario.

Sin embargo, cuando tu app regrese al primer plano, deberás confirmar que la actualización no está detenida en el estado UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS. Si la actualización se detiene en este estado, reanúdala, como se muestra a continuación:

Kotlin

    // Checks that the update is not stalled during 'onResume()'.
    // However, you should execute this check at all entry points into the app.
    override fun onResume() {
        super.onResume()

        appUpdateManager
            .appUpdateInfo
            .addOnSuccessListener { appUpdateInfo ->
                ...
                if (appUpdateInfo.updateAvailability()
                    == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS
                ) {
                    // If an in-app update is already running, resume the update.
                    appUpdateManager.startUpdateFlowForResult(
                        appUpdateInfo,
                        IMMEDIATE,
                        this,
                        MY_REQUEST_CODE
                    );
                }
            }
    }
    

Java

    // Checks that the update is not stalled during 'onResume()'.
    // However, you should execute this check at all entry points into the app.
    @Override
    protected void onResume() {
      super.onResume();

      appUpdateManager
          .getAppUpdateInfo()
          .addOnSuccessListener(
              appUpdateInfo -> {
                ...
                if (appUpdateInfo.updateAvailability()
                    == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
                    // If an in-app update is already running, resume the update.
                    appUpdateManager.startUpdateFlowForResult(
                        appUpdateInfo,
                        IMMEDIATE,
                        this,
                        MY_REQUEST_CODE);
                }
              });
    }
    

Cómo solucionar problemas

En esta sección, se describen algunas posibles soluciones para casos en que las actualizaciones dentro de la app pueden no funcionar como se espera durante las pruebas.

  • Las actualizaciones dentro de la app están disponibles solo para las cuentas de usuario propietarias de la app. Por lo tanto, asegúrate de que la cuenta que estás usando haya descargado tu aplicación desde Google Play al menos una vez antes de usarla para probar las actualizaciones dentro de la app.
  • Asegúrate de que la aplicación con la que estés probando las actualizaciones dentro de la app tenga el mismo ID de aplicación y esté firmada con la misma clave de firma que la que está disponible en Google Play.
  • Debido a que Google Play solo puede actualizar una app a un código de versión posterior, asegúrate de que la aplicación que estés probando tenga un código de versión anterior al código de la actualización.
  • Asegúrate de que la cuenta sea apta y de que la caché de Google Play esté actualizada. Para hacerlo, accede a la cuenta de Google Play Store en el dispositivo de prueba y sigue estos pasos:
    1. Asegúrate de cerrar completamente la app de Google Play Store.
    2. Abre la app de Google Play Store y ve a la pestaña Mis apps y juegos.
    3. Si la app que estás probando no aparece con una actualización disponible, verifica que hayas configurado correctamente los segmentos de prueba.