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 (AWP) a través de Trusted Web Activity, el service worker aún no estará disponible, ya que aún no se ha realizado el proceso de registro. Además, si el usuario no tiene conectividad durante el primer inicio de la app, en lugar de la experiencia personalizada sin conexión, se mostrará 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. Por lo tanto, si el usuario no tiene conectividad cuando intenta 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, verifica el estado de la red antes de iniciar la actividad web de confianza.

Cómo crear una LauncherActivity personalizada

El primer paso es crear una actividad de inicio personalizada. Este objeto Activity, que 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 se extienda: com.google.androidbrowserhelper.trusted.LauncherActivity.

import com.google.androidbrowserhelper.trusted.LauncherActivity;

public class OfflineFirstTWALauncherActivity extends LauncherActivity {

}

Luego, 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 actividad de inicio y define https://airhorner.com como la URL que se abrirá cuando se inicie el TWA.

Controla situaciones sin conexión

Primero, dentro de la actividad, anula el método shouldLaunchImmediately() y haz que muestre false para que la actividad web de confianza 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 la TWA. Agrega una llamada a tryLaunchTwa(), un método auxiliar 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 la TWA se inició anteriormente, el service worker está registrado y la AWP podrá responder sin conexión. En ese caso, llama a launchTwa(), que se define en la clase superior, para iniciar la actividad web de confianza directamente.
  • Si la TWA no se inició con anterioridad 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 aún no se inició la TWA y el usuario está sin conexión, renderiza la pantalla de resguardo sin conexión nativa.

Implementa métodos auxiliares

El paso final es implementar los métodos auxiliares a los que llama 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() de la clase superior y guarda la marca twa_launched_successfully en las preferencias compartidas. Esto indica que la TWA se inició correctamente, al menos una vez.

El método auxiliar restante, renderOfflineFallback(), 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 de activity_offline_first_twa, que contiene un botón para volver a intentarlo, que, a tiempo, ejecutará firstTimeLaunchTwa() después de verificar la conexión.

twa sin conexión - pantalla personalizada sin conexión

Conclusión

  • La primera vez que un usuario inicie una app web progresiva (AWP) a través de Trusted Web Activity, el service worker aún no estará disponible.
  • Para evitar que se muestre 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 de resguardo sin conexión.
  • En esta guía, aprendiste a implementar esa estrategia. Si te interesa verificar el código que usamos en esta guía, puedes encontrar la solución completa en la Demostración de primera TWA sin conexión.