Guide d’implémentation

Un exemple complet est disponible sur l’exemple d’application GitHub. Il contient des classes réutilisables pour personnaliser l’interface utilisateur, se connecter au service d’arrière-plan et gérer le cycle de vie de l’application et de l’activité de l’onglet personnalisé.

Si vous suivez les instructions de cette page, vous pourrez créer une excellente intégration.

La première étape d’une intégration d’onglets personnalisés consiste à ajouter la bibliothèque du navigateur AndroidX à votre projet. Ouvrez le fichier app/build.gradle et ajoutez la bibliothèque du navigateur à la section dépendances.

dependencies {
...
implementation "androidx.browser:browser:1.3.0"
}

Une fois la bibliothèque du navigateur ajoutée à votre projet, il existe deux ensembles de personnalisations possibles:

  • Personnalisation de l’interface utilisateur et interaction avec les onglets personnalisés.
  • Accélérer le chargement de la page et maintenir l’application en vie.

Les personnalisations de l’interface utilisateur sont effectuées en utilisant les classes CustomTabsIntent et CustomTabsIntent.Builder; les améliorations de performances sont obtenues en utilisant le CustomTabsClient pour se connecter au service d’onglets personnalisés, réchauffer le navigateur et lui faire savoir quelles URL seront ouvertes.

Ouverture d’un Onglet personnalisé #

Un CustomTabsIntent.Builder peut être utilisé pour configurer un onglet personnalisé. Une fois prêt, appelez CustomTabsIntent.Builder.build pour créer un CustomTabsIntent et lancez l’URL souhaitée avec CustomTabsIntent.launchUrl.

String url = ¨https://paul.kinlan.me/¨;
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(this, Uri.parse(url));

Configurer la couleur de la barre d’adresse #

L’un des aspects les plus importants (et les plus simples à implémenter) des onglets personnalisés est la possibilité pour vous de changer la couleur de la barre d’adresse pour qu’elle soit cohérente avec le thème de votre application.

L’extrait ci-dessous change la couleur d’arrière-plan de la barre d’adresse. colorInt est un int qui spécifie un Color.

int coolorInt = Color.parseColor("#FF0000"); //red
builder.setToolbarColor(colorInt);

Configurez un bouton d’action personnalisé #

builder.setActionButton(icon, description, pendingIntent, tint);

Capture d'écran du Bouton d'action dans l'application Tumblr

En tant que développeur de votre application, vous avez le contrôle total sur le Bouton d’action présenté à vos utilisateurs dans l’onglet du navigateur.

Dans la plupart des cas, il s’agira d’une action principale telle que Partager, ou d’une autre activité commune que vos utilisateurs effectueront.

Le bouton d’action est représenté comme un ensemble avec une icône du bouton d’action et un PendingIntent qui sera appelé par le navigateur lorsque votre utilisateur clique sur le bouton d’action. L’icône est currenlty 24dp en hauteur et 24-48 dp en largeur.

Il peut être personnalisé en appelant CustomTabsIntentBuilder#setActionButton:

  • icon est un Bitmap à utiliser comme source d’image pour le bouton d’action.
  • description est un String être utilisé comme description accessible pour le bouton.
  • pendingIntent est un PendingIntent à lancer lorsque le bouton d’action ou l’élément de menu a été appuyé. Le navigateur appellera PendingIntent#send lors des taps après avoir ajouté l’URL en tant que données. L’application cliente peut appeler Intent#getDataString pour obtenir l’URL.
  • tint est un booléen qui définit si le bouton d’action doit être teinté.

Configurer un menu personnalisé #

builder.addMenuItem(menuItemTitle, menuItemPendingIntent);

Capture d'écran du menu de l'application Twitter

Le navigateur dispose d’un menu complet d’actions que les utilisateurs effectueront fréquemment dans un navigateur, mais elles peuvent ne pas être pertinentes pour le contexte de votre application.

Les onglets personnalisés auront un ensemble d’actions par défaut fournies par le navigateur. Ces actions peuvent inclure des éléments tels que « Transférer », « Informations sur la page », « Actualiser », « Rechercher dans la page » ou « Ouvrir dans le navigateur ».

En tant que développeur, vous pouvez ajouter et personnaliser jusqu’à cinq éléments de menu qui apparaîtront entre la ligne d’icônes et les éléments de pied.

Un élément de menu est ajouté en appelant CustomTabsIntent.Builder#addMenuItem avec title et un PendingIntent que le navigateur appellera en votre nom lorsque l’utilisateur tapera sur l’élément sont passés en tant que paramètres.

Configurer des animations d’entrée et de sortie personnalisées #

De nombreuses applications Android utilisent des animations d’entrée et de sortie personnalisées lors de la transition entre les activités sur Android. Les onglets personnalisés ne sont pas différents, vous pouvez modifier les animations d’entrée et de sortie (lorsque l’utilisateur appuie en arrière) pour les garder cohérentes avec le reste de votre application.

builder.setStartAnimations(this, R.anim.slide_in_right, R.anim.slide_out_left);
builder.setExitAnimations(this, R.anim.slide_in_left, R.anim.slide_out_right);

Réchauffez le navigateur pour accélérer le chargement des pages #

Par défaut, lorsque CustomTabsIntent#launchUrl est appelé, il fait tourner le navigateur et lance l’URL. Cela peut prendre un temps précieux et avoir un impact sur la perception de la douceur.

Nous pensons que les utilisateurs exigent une expérience quasi instantanée, nous avons donc fourni un Service auquel votre application peut se connecter et indiquer au navigateur et à ses composants natifs de se réchauffer. Les onglets personnalisés offrent également la possibilité pour vous, le développeur, d’indiquer au navigateur l’ensemble probable de pages Web que l’utilisateur visitera. Les navigateurs pourront alors effectuer :

  • Pré-résolution DNS du domaine principal
  • Pré-résolution DNS des sous-ressources les plus probables
  • Pré-connexion à la destination, y compris la négociation HTTPS/TLS.

Le processus de réchauffement du navigateur est le suivant :

  • Utilisez CustomTabsClient#bindCustomTabsService pour vous connecter au service.
  • Une fois le service connecté, appelez CustomTabsClient#warmup pour démarrer le navigateur en coulisses.
  • Appelez CustomTabsClient#newSession pour créer une nouvelle session. Cette session est utilisée pour toutes les requêtes à l’API.
  • En option, attachez un CustomTabsCallback en paramètre lors de la création d’une nouvelle session, de sorte que vous sachiez qu’une page a été chargée.
  • Indique au navigateur les pages que l’utilisateur est susceptible de charger avec CustomTabsSession#mayLaunchUrl
  • Appelez le constructeur CustomTabsIntent.Builder en passant le CustomTabsSession créé en paramètre.

Connectez-vous au service d’onglets personnalisés #

La méthode CustomTabsClient#bindCustomTabsService élimine la complexité de la connexion au service d’onglets personnalisés.

Créez une classe qui étend CustomTabsServiceConnection et utilisez onCustomTabsServiceConnected pour obtenir une instance du CustomTabsClient. Cette instance sera nécessaire lors des prochaines étapes.

// Package name for the Chrome channel the client wants to connect to. This
// depends on the channel name.
// Stable = com.android.chrome
// Beta = com.chrome.beta
// Dev = com.chrome.dev
public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
mCustomTabsClient = client;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
boolean ok = CustomTabsClient.bindCustomTabsService(this, mPackageNameToBind, connection);

Réchauffe le processus du navigateur #

boolean warmup(long flags)

Réchauffe le processus du navigateur et charge les bibliothèques natives. L’échauffement est asynchrone, la valeur de retour indique si la demande a été acceptée. Plusieurs appels réussis retourneront également true.

Renvoie true en cas de succès.

Créer un nouvel onglet session #

boolean newSession(CustomTabsCallback callback)

La session est utilisée dans les appels suivants pour lier l’appel mayLaunchUrl, le CustomTabsIntent et l’onglet générés l’un à l’autre. Le rappel fourni ici est associé à la session créée. Toutes les mises à jour de la session créée (voir Rappel des onglets personnalisés ci-dessous) sont également reçues via ce rappel. Renvoie si une session a été créée avec succès. Plusieurs appels avec le même CustomTabsCallback ou une valeur null renverront false.

Indiquez au navigateur les URL que l’utilisateur est susceptible d’ouvrir #

boolean mayLaunchUrl(Uri url, Bundle extras, List<Bundle> otherLikelyBundles)

Cette méthode CustomTabsSession indique au navigateur une navigation future probable vers une URL. La méthode warmup() doit être appelée en premier en tant que meilleure pratique. L’URL la plus probable doit d’abord être spécifiée. En option, une liste d’autres URL probables peut être fournie. Ils sont traités comme étant moins probables que le premier et doivent être triés par ordre de priorité décroissant. Ces URL supplémentaires peuvent être ignorées. Tous les appels précédents à cette méthode seront privés de priorité. Renvoie si l’opération s’est terminée avec succès.

Rappel de connexion des onglets personnalisés #

void onNavigationEvent(int navigationEvent, Bundle extras)

Sera appelé lorsqu’un événement de navigation se produit dans l’onglet personnalisé. navigationEvent int est l’une des 6 valeurs qui définit l’état de la page. Voir ci-dessous pour plus d’informations.

/**
* Sent when the tab has started loading a page.
*/
public static final int NAVIGATION_STARTED = 1;
/**
* Sent when the tab has finished loading a page.
*/
public static final int NAVIGATION_FINISHED = 2;
/**
* Sent when the tab couldn't finish loading due to a failure.
*/
public static final int NAVIGATION_FAILED = 3;
/**
* Sent when loading was aborted by a user action before it finishes like clicking on a link
* or refreshing the page.
*/
public static final int NAVIGATION_ABORTED = 4;
/**
* Sent when the tab becomes visible.
*/
public static final int TAB_SHOWN = 5;
/**
* Sent when the tab becomes hidden.
*/
public static final int TAB_HIDDEN = 6;

Que se passe-t-il si l’utilisateur n’a pas de navigateur prenant en charge les onglets personnalisés installés? #

Les onglets personnalisés sont pris en charge par la plupart des navigateurs Android. Néanmoins, comme il utilise une intention ACTION_VIEW avec des extras clés pour personnaliser l’interface utilisateur, il s’ouvrira dans le navigateur système ou le navigateur par défaut de l’utilisateur si les onglets personnalisés ne sont pas pris en charge.

Si l’utilisateur a installé un navigateur prenant en charge l’onglet personnalisé et qu’il s’agit du navigateur par défaut, il récupérera automatiquement les EXTRAS et présentera une interface utilisateur personnalisée.

Comment puis-je vérifier si l’appareil Android dispose d’un navigateur prenant en charge l’onglet personnalisé? #

Il est possible d’utiliser le PackageManager pour interroger l’appareil Android à la recherche d’applications pouvant gérer des onglets personnalisés. Nous recherchons des applications capables de gérer les intentions http, puis vérifions si ces applications déclarent également la prise en charge du service d’onglets personnalisés:

/**
* Returns a list of packages that support Custom Tabs.
*/
public static ArrayList<ResolveInfo> getCustomTabsPackages(Context context) {
PackageManager pm = context.getPackageManager();
// Get default VIEW intent handler.
Intent activityIntent = new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.fromParts("http", "", null));
// Get all apps that can handle VIEW intents.
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
ArrayList<ResolveInfo> packagesSupportingCustomTabs = new ArrayList<>();
for (ResolveInfo info : resolvedActivityList) {
Intent serviceIntent = new Intent();
serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
serviceIntent.setPackage(info.activityInfo.packageName);
// Check if this package also resolves the Custom Tabs service.
if (pm.resolveService(serviceIntent, 0) != null) {
packagesSupportingCustomTabs.add(info);
}
}
return packagesSupportingCustomTabs;
}

Android 11 a introduit des changements de visibilité du package. Si votre application Android cible le niveau d’API 30 ou supérieur, l’ajout d’une section queriesAndroidManifest.xml est nécessaire, sinon l’extrait de code ci-dessus ne renverra pas de résultats :

<queries>
<intent>
<action android:name=
"android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.