Atividades confiáveis na Web que priorizam o modo off-line

Demián Renzulli
Demián Renzulli

Na primeira vez que um usuário iniciar um Progressive Web App (PWA) por meio de uma atividade confiável na Web, o service worker ainda não estará disponível, porque o processo de registro ainda não ocorreu. Além disso, se o usuário não tiver conectividade durante a primeira inicialização do app, em vez da experiência off-line personalizada, a página de erro de rede será mostrada.

Um exemplo desse cenário pode ocorrer depois que o usuário faz o download do PWA na Play Store. Portanto, se o usuário não tiver conectividade ao tentar abrir o app pela primeira vez, o service worker ainda não estará disponível para mostrar a página substituta off-line. A página de erro padrão será mostrada, levando a uma experiência ruim.

TWA off-line: a página off-line padrão

Este guia explica como mostrar sua própria atividade nessa situação verificando o status da rede antes de iniciar a atividade confiável na Web.

Criar uma LauncherActivity personalizada

A primeira etapa é criar uma atividade personalizada da tela de início. Esse Activity que contém a tela off-line para mostrar se não há conectividade na primeira vez que um usuário abrir o app.

Chame a atividade OfflineFirstTWALauncherActivity e faça-a estender: com.google.androidbrowserhelper.trusted.LauncherActivity.

import com.google.androidbrowserhelper.trusted.LauncherActivity;

public class OfflineFirstTWALauncherActivity extends LauncherActivity {

}

Em seguida, registre a atividade em 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>

O código anterior registra OfflineFirstTWALauncherActivity como uma atividade da tela de início e define https://airhorner.com como o URL a ser aberto quando a TWA for iniciada.

Lidar com cenários off-line

Primeiro, dentro da atividade, substitua o método shouldLaunchImmediately() e faça com que ele retorne false para que a atividade confiável na Web não seja iniciada imediatamente. Também é possível adicionar outras verificações antes do lançamento 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;
}

Modifique o método onCreate() para verificar o status da rede antes que a TWA seja iniciada. Adicione uma chamada para tryLaunchTwa(), um método auxiliar que conterá essa lógica:

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

Em seguida, implemente 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();
    }
}

O código anterior lida com três cenários:

  • Se o TWA tiver sido iniciado anteriormente, o service worker estará registrado e o PWA poderá responder off-line. Nesse caso, chame launchTwa(), definido na classe mãe, para iniciar a Atividade confiável na Web diretamente.
  • Se a TWA não tiver sido iniciada anteriormente e o usuário estiver on-line, inicie a Atividade confiável na Web pela primeira vez usando o método firstTimeLaunchTwa(), que será implementado mais tarde.
  • Se a TWA ainda não tiver sido iniciada e o usuário estiver off-line, renderize a tela substituta off-line nativa.

Implementar métodos auxiliares

A etapa final é implementar os métodos auxiliares chamados pelo código anterior. Este é o código para verificar o estado off-line isOnline():

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

Em seguida, implemente hasTwaLaunchedSuccessfully(), que verifica se o TWA foi iniciado pelo menos uma 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);
}

O código anterior chama o launchTWA() da classe mãe e salva a flag twa_launched_successfully nas preferências compartilhadas. Isso indica que o TWA foi lançado com sucesso, pelo menos uma vez.

O método auxiliar restante, renderOfflineFallback(), renderiza uma tela off-line do Android.

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();
        }
    });
}

Fort, a demonstração dele, definimos o layout activity_offline_first_twa, que contém um botão para tentar novamente, que, a tempo, executará firstTimeLaunchTwa() depois de verificar a conexão.

twa off-line - tela off-line personalizada

Conclusão

  • Na primeira vez que um usuário iniciar um Progressive Web App (PWA) por meio de uma atividade confiável na Web, o service worker ainda não estará disponível.
  • Para evitar que a tela off-line padrão seja mostrada se o usuário não tiver conectividade, você pode detectar a condição off-line e mostrar uma tela off-line substituta.
  • Neste guia, você aprendeu a implementar essa estratégia. Se você quiser verificar o código que usamos neste guia, encontre a solução completa na Demonstração da primeira TWA off-line.