-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Chrome Custom Tabs
Chrome custom tabs give apps more control over their web experience, and make transitions between native and web content more seamless without having to resort to a WebView.
Chrome custom tabs allow an app to customize how Chrome looks and feels. An app can change things like:
- Toolbar color
- Enter and exit animations
- Add custom actions to the Chrome toolbar and overflow menu
Chrome custom tabs also allow the developer to pre-start Chrome and pre-fetch content for faster loading.
See the official integration guide for more ways to use Chrome Custom Tabs.
You will need to have the Chrome app installed on your phone. If you are using an emulator, you must setup Google Play Services and install the Chrome app though the Play store.
Add the AndroidX Browser library for Chrome Custom Tabs as a dependency to your gradle build file:
implementation 'androidx.browser:browser:1.10.0'The library requires API 23 (Marshmallow) and above. If you are supporting a lower API level, pin an older release (the 1.9.x line still supported API 21) or add <uses-sdk tools:overrideLibrary="androidx.browser"/> to your manifest to force its use and check the API version at runtime before launching a Chrome Custom Tab.
The most basic example to launch a Chrome tab is through a custom intent as shown below:
// Use a CustomTabsIntent.Builder to configure CustomTabsIntent.
String url = "https://www.codepath.com/";
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
// set toolbar color and/or setting custom actions before invoking build()
// Once ready, call CustomTabsIntent.Builder.build() to create a CustomTabsIntent
CustomTabsIntent customTabsIntent = builder.build();
// and launch the desired Url with CustomTabsIntent.launchUrl()
customTabsIntent.launchUrl(this, Uri.parse(url));If you do not have Chrome installed, the intent will launch the default browser installed on the device. The CustomTabsIntent simply launches an implicit intent (android.intent.action.VIEW) and passes an extra data in the intent (i.e. android.support.customtabs.extra.SESSION and android.support.customtabs.extra.TOOLBAR_COLOR) that gets ignored if the default browser cannot process this information.
Configuring additional options requires using the builder class. If you wish to add custom icons or actions to the menu, you will need to create pending intents to do so.
setToolbarColor(int) (along with setSecondaryToolbarColor, setNavigationBarColor, and setNavigationBarDividerColor) was deprecated in androidx.browser:browser:1.3.0 (released December 2, 2020). On current versions, build a CustomTabColorSchemeParams and pass it via setDefaultColorSchemeParams() — you can also vary the colors per system color scheme with setColorSchemeParams(int scheme, CustomTabColorSchemeParams params):
CustomTabColorSchemeParams params = new CustomTabColorSchemeParams.Builder()
.setToolbarColor(ContextCompat.getColor(this, R.color.colorAccent))
.build();
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder()
.setDefaultColorSchemeParams(params);ContextCompat.getColor() (from androidx.core:core) remains the preferred way to resolve a color resource: Resources.getColor(int) was deprecated in API 23 in favor of the theme-aware overload, and ContextCompat.getColor() handles both pre- and post-23 devices.
By default, a Chrome tab does not include share action in the toolbar. However, you can add a default one to the menu item list:
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
// add share action to menu list
builder.addDefaultShareMenuItem();
If you want to add a specific icon (such as the share icon) to the toolbar, you need to first should add the icon using New -> Image Asset (currently, Chrome Tabs do not support vector drawables so you should be using PNG files as your icons):
Note the file that is saved. We will need to create a bitmap for use later:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_name);Next, create the intent:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "http://www.codepath.com");Next, you need to create a pending intent (see this YouTube clip for more info), which is used to wake up your app when the user clicks on the icon. This pending intent needs to be passed to the Chrome Tabs intent builder:
int requestCode = 100;
PendingIntent pendingIntent = PendingIntent.getActivity(this,
requestCode,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);Finally, we need to pass the bitmap, text, and pending intent created:
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
// Map the bitmap, text, and pending intent to this icon
// Set tint to be true so it matches the toolbar color
builder.setActionButton(bitmap, "Share Link", pendingIntent, true);
CustomTabsIntent customTabsIntent = builder.build();Chrome custom tabs also allow the developer to pre-start the browser and pre-fetch content for faster loading. The modern flow uses androidx.browser's CustomTabsClient, CustomTabsServiceConnection, and CustomTabsSession directly — no third-party helper files required. Per Chrome's warm-up and pre-fetch guide, the steps are:
- Bind to the Custom Tabs service with
CustomTabsClient.bindCustomTabsService(context, packageName, connection). - In
CustomTabsServiceConnection.onCustomTabsServiceConnected(...), callclient.warmup(0)to spin Chrome up in the background (saves ~700ms per the official guide). - Create a session with
client.newSession(callback)and callsession.mayLaunchUrl(url, null, null)to speculatively pre-fetch URLs the user is likely to visit. - Pass that session into
new CustomTabsIntent.Builder(session)when you finally launch.
A complete, copy-pasteable sample lives in the official guide above; a runnable demo app is in GoogleChrome/android-browser-helper (the actively maintained replacement for the old custom-tabs-client repo, which was archived in January 2023).
To fall back to the default browser when no Custom Tabs–capable browser is installed, ask CustomTabsClient.getPackageName(context, null) for the preferred Custom Tabs provider — it returns null if none is available. When a provider is found, pin the intent to that package via customTabsIntent.intent.setPackage(...) so the tab is actually rendered by that browser instead of being silently re-routed to whatever the system default ACTION_VIEW handler happens to be:
String packageName = CustomTabsClient.getPackageName(this, null);
if (packageName != null) {
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
customTabsIntent.intent.setPackage(packageName);
customTabsIntent.launchUrl(this, uri);
} else {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
}The above quick integration example will open your Uri on a Chrome Custom Tab without warming up, pre-fetching or UI customizations.
For warm-up, pre-fetching, and the full CustomTabsServiceConnection flow, follow Chrome's warm-up and pre-fetch guide. Runnable end-to-end samples (session handling, ephemeral tabs, navigation callbacks, OAuth flows, custom headers, and UI customization) live in the GoogleChrome/android-browser-helper demos.
For an exhaustive list of UI customization options exposed by CustomTabsIntent.Builder, see the androidx.browser reference.
- https://developer.chrome.com/docs/android/custom-tabs
- https://developer.chrome.com/docs/android/custom-tabs/integration-guide
- https://developer.chrome.com/docs/android/custom-tabs/guide-warmup-prefetch
- https://developer.android.com/jetpack/androidx/releases/browser
- https://github.com/GoogleChrome/android-browser-helper
Created by CodePath with much help from the community. Contributed content licensed under cc-wiki with attribution required. You are free to remix and reuse, as long as you attribute and use a similar license.
Finding these guides helpful?
We need help from the broader community to improve these guides, add new topics and keep the topics up-to-date. See our contribution guidelines here and our topic issues list for great ways to help out.
Check these same guides through our standalone viewer for a better browsing experience and an improved search. Follow us on twitter @codepath for access to more useful Android development resources.