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);
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 unBitmap
à utiliser comme source d’image pour le bouton d’action. -
description
est unString
être utilisé comme description accessible pour le bouton. -
pendingIntent
est unPendingIntent
à lancer lorsque le bouton d’action ou l’élément de menu a été appuyé. Le navigateur appelleraPendingIntent#send
lors des taps après avoir ajouté l’URL en tant que données. L’application cliente peut appelerIntent#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);
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 leCustomTabsSession
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 queries
AndroidManifest.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>