How can I open a URL in Android's web browser from my application?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To open a URL in Android's browser, create an Intent with ACTION_VIEW and a parsed Uri. Android resolves the intent to the default browser or presents a chooser if multiple browsers are installed. For a more integrated experience, Chrome Custom Tabs open web content inside your app without a full browser launch. Since Android 11 (API 30), package visibility restrictions affect how you query for browser apps, requiring a <queries> declaration in your manifest.
Basic Intent Approach
Android finds an activity that handles ACTION_VIEW with an https:// URI — typically the default browser. This works for http://, https://, file://, and other registered URI schemes.
Handling Missing Browser
If no browser is installed (rare but possible on embedded devices), startActivity throws ActivityNotFoundException:
Or check before launching:
Forcing a Browser Chooser
If you want the user to pick a browser instead of using the default:
Chrome Custom Tabs (In-App Browser)
Custom Tabs open web content inside your app with a Chrome-powered view, providing faster loading and a customizable UI:
Custom Tabs advantages:
- Faster than launching a full browser (pre-warming available)
- Shares cookies and sessions with Chrome
- Customizable toolbar color and animations
- Falls back to a regular browser if Chrome is not installed
Customizing Chrome Custom Tabs
WebView (Embedded Browser)
For full control over web content rendering within your app:
Use WebView when you need to intercept navigation, inject JavaScript, or display web content as part of your app UI. Use intents or Custom Tabs for simply viewing external links.
Android 11+ Package Visibility
Starting with Android 11 (API 30), you need to declare which packages you query for in your manifest:
Without the <queries> block, intent.resolveActivity() may return null even when browsers are installed.
Jetpack Compose
LocalUriHandler is the Compose-idiomatic way to open URLs. It uses ACTION_VIEW internally.
Common Pitfalls
- Not catching
ActivityNotFoundException: On some devices (especially Android TV or embedded systems), no browser may be installed. Always wrapstartActivityin a try/catch or check withresolveActivity()first. - Missing
https://scheme: Passing"www.example.com"withouthttps://causes the intent to fail because Android cannot determine the intent type. Always include the full scheme in the URL. - Forgetting
<queries>on Android 11+: Without the<queries>declaration in your manifest,resolveActivity()returns null for browser intents on API 30+, even though browsers are available. - Using WebView for external links: WebView is heavyweight, requires managing the back stack, JavaScript, and security. For simply opening a link, use an intent or Custom Tabs which handle all of this automatically.
- Not adding internet permission for WebView:
<uses-permission android:name="android.permission.INTERNET" />is required for WebView to load any URL. The intent-based approaches do not need this permission since the browser app handles networking.
Summary
- Use
Intent(ACTION_VIEW, Uri.parse(url))to open URLs in the default browser - Use Chrome Custom Tabs for an in-app browser experience with faster loading and customizable UI
- Use WebView only when you need full control over the web content rendering
- Always handle
ActivityNotFoundExceptionfor devices without browsers - Declare
<queries>in your manifest for Android 11+ package visibility - In Jetpack Compose, use
LocalUriHandler.current.openUri(url)

