Actividades web de confianza que priorizan el uso sin conexión

Demián Renzulli
Demián Renzulli

La primera vez que un usuario inicia una app web progresiva (PWA) a través de la actividad web confiable, el servicio de trabajo aún no estará disponible, ya que el proceso de registro aún no se ha realizado. Además, si el usuario no tiene conectividad durante el primer inicio de la app, en lugar de la experiencia sin conexión personalizada, se muestra la página de error de red.

Un ejemplo de esta situación puede ocurrir después de que el usuario descarga la AWP desde Play Store. Si el usuario no tiene conectividad cuando intente abrir la app por primera vez, el service worker aún no estará disponible para mostrar la página de resguardo sin conexión. Se mostrará la página de error estándar, lo que generará una mala experiencia.

TWA sin conexión: la página sin conexión estándar

En esta guía, se explica cómo mostrar tu propia actividad en esta situación. Para ello, debes verificar el estado de la red antes de iniciar la Actividad web confiable.

Crea una LauncherActivity personalizada

El primer paso es crear una actividad de selector personalizada. Este Activity contendrá la pantalla sin conexión para mostrar si no hay conectividad la primera vez que un usuario abre la app.

Llama a la actividad OfflineFirstTWALauncherActivity y haz que extienda: com.google.androidbrowserhelper.trusted.LauncherActivity.

import com.google.androidbrowserhelper.trusted.LauncherActivity;

public class OfflineFirstTWALauncherActivity extends LauncherActivity {

}

A continuación, registra la actividad en AndroidManifest.xml:

<activity android:name=".OfflineFirstTWALauncherActivity" android:theme="@style/Theme.Design.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <!-- Edit android:value to change the url opened by the Trusted Web Activity -->
    <meta-data android:name="android.support.customtabs.trusted.DEFAULT_URL" android:value="https://airhorner.com" />
    <!-- This intent-filter adds the Trusted Web Activity to the Android Launcher -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Edit android:host to handle links to the target URL -->
        <data android:host="airhorner.com" android:scheme="https" />
    </intent-filter>
</activity>

El código anterior registra OfflineFirstTWALauncherActivity como una actividad de selector y define https://airhorner.com como la URL que se abrirá cuando se inicie la TWA.

Controla situaciones sin conexión

Primero, dentro de la actividad, anula el método shouldLaunchImmediately() y haz que muestre false, de modo que la actividad web confiable no se inicie de inmediato. También puedes agregar verificaciones adicionales antes del lanzamiento inicial:

@Override
protected boolean shouldLaunchImmediately() {
    // launchImmediately() returns `false` so we can check connection
    // and then render a fallback page or launch the Trusted Web Activity with `launchTwa()`.
    return false;
}

Anula el método onCreate() para verificar el estado de la red antes de que se inicie el TWA. Agrega una llamada a tryLaunchTwa(), un método de ayuda que contendrá esa lógica:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    tryLaunchTwa();
}

A continuación, implementa tryLaunchTwa():

private void tryLaunchTwa() {
    // If TWA has already launched successfully, launch TWA immediately.
    // Otherwise, check connection status. If online, launch the Trusted Web Activity with `launchTwa()`.
    // Otherwise, if offline, render the offline fallback screen.
    if (hasTwaLaunchedSuccessfully()) {
        launchTwa();
    } else if (isOnline()) {
        firstTimeLaunchTwa();
    } else {
        renderOfflineFallback();
    }
}

El código anterior controla tres situaciones:

  • Si se inició la TWA anteriormente, se registró el trabajador de servicio y la AWP podrá responder sin conexión. En ese caso, llama a launchTwa(), definido en la clase superior, para iniciar la actividad web confiable directamente.
  • Si la TWA no se inició anteriormente y el usuario está en línea, inicia la actividad web de confianza por primera vez con el método firstTimeLaunchTwa() que implementarás más adelante.
  • Si el TWA aún no se inició y el usuario no tiene conexión, renderiza la pantalla de resguardo sin conexión nativa.

Implementa métodos auxiliares

El último paso es implementar los métodos auxiliares a los que llamó el código anterior. Este es el código para verificar el estado sin conexión isOnline():

private boolean isOnline() {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

A continuación, implementa hasTwaLaunchedSuccessfully(), que verifica si la TWA se inició al menos una vez:

private boolean hasTwaLaunchedSuccessfully() {
    // Return `true` if the preference "twa_launched_successfully" has already been set.
    SharedPreferences sharedPref = getSharedPreferences(getString(R.string.twa_offline_first_preferences_file_key), Context.MODE_PRIVATE);
    return sharedPref.getBoolean(getString(R.string.twa_launched_successfully), false);
}

El código anterior llama a launchTWA() desde la clase superior y guarda la marca twa_launched_successfully en las preferencias compartidas. Esto indica que la TWA se lanzó correctamente, al menos una vez.

renderOfflineFallback(), el método auxiliar restante, renderiza una pantalla de Android sin conexión.

private void renderOfflineFallback() {
    setContentView(R.layout.activity_offline_first_twa);

    Button retryBtn = this.findViewById(R.id.retry_btn);
    retryBtn.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            // Check connection status. If online, launch the Trusted Web Activity for the first time.
            if (isOnline()) firstTimeLaunchTwa();
        }
    });
}

Para esta demostración, definimos el diseño activity_offline_first_twa, que contiene un botón para volver a intentarlo, que, con el tiempo, ejecutará firstTimeLaunchTwa() después de verificar la conexión.

twa sin conexión: pantalla sin conexión personalizada

Conclusión

  • La primera vez que un usuario inicie una app web progresiva (AWP) a través de la actividad web confiable, el service worker aún no estará disponible.
  • Para evitar mostrar la pantalla sin conexión estándar si el usuario no tiene conectividad, puedes detectar la condición sin conexión y mostrar una pantalla sin conexión de resguardo.
  • En esta guía, aprendiste a implementar esa estrategia. Si te interesa verificar el código que usamos a lo largo de esta guía, puedes encontrar la solución completa en la demo de TWA sin conexión.