Android development
deep linking
app startup
browser integration
mobile development

Make a link in the Android browser start up my app?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want a browser link to open your Android app, you need deep linking. Android can route a matching URL to an activity in your app, either through a custom scheme such as myapp:// or through verified HTTPS App Links.

For production apps, verified HTTPS links are usually the better option. They behave more like normal web URLs, work better with user trust, and avoid collisions with other apps that might claim the same custom scheme.

The entry point is an intent filter in AndroidManifest.xml. It declares which URL pattern your activity can handle.

xml
1<activity
2    android:name=".ProductActivity"
3    android:exported="true">
4    <intent-filter>
5        <action android:name="android.intent.action.VIEW" />
6        <category android:name="android.intent.category.DEFAULT" />
7        <category android:name="android.intent.category.BROWSABLE" />
8
9        <data
10            android:scheme="myapp"
11            android:host="product" />
12    </intent-filter>
13</activity>

With that manifest entry, a link such as myapp://product?id=42 can start the activity. Inside the activity, read the incoming URI from the launching intent.

kotlin
1import android.net.Uri
2import android.os.Bundle
3import androidx.appcompat.app.AppCompatActivity
4
5class ProductActivity : AppCompatActivity() {
6    override fun onCreate(savedInstanceState: Bundle?) {
7        super.onCreate(savedInstanceState)
8
9        val uri: Uri? = intent?.data
10        val productId = uri?.getQueryParameter("id")
11        println("Open product: $productId")
12    }
13}

Custom schemes are easy to set up, but App Links are better when the link should also work on the web. They use normal HTTPS URLs and let Android verify that your domain trusts your app.

Manifest example:

xml
1<activity
2    android:name=".ProductActivity"
3    android:exported="true">
4    <intent-filter android:autoVerify="true">
5        <action android:name="android.intent.action.VIEW" />
6        <category android:name="android.intent.category.DEFAULT" />
7        <category android:name="android.intent.category.BROWSABLE" />
8
9        <data
10            android:scheme="https"
11            android:host="example.com"
12            android:pathPrefix="/products" />
13    </intent-filter>
14</activity>

Then publish an assetlinks.json file on your domain at https://example.com/.well-known/assetlinks.json.

json
1[
2  {
3    "relation": ["delegate_permission/common.handle_all_urls"],
4    "target": {
5      "namespace": "android_app",
6      "package_name": "com.example.app",
7      "sha256_cert_fingerprints": [
8        "12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF"
9      ]
10    }
11  }
12]

Once verified, tapping https://example.com/products?id=42 can open the app directly.

Handle Fallbacks Gracefully

Not every user will have the app installed. That is another reason HTTPS links are useful: the same URL can open the website when the app is missing.

Your application code should also validate the incoming URI. Treat it like external input. Check path segments, query parameters, and authentication state before navigating to sensitive screens.

If the target screen depends on login, redirect unauthenticated users through your normal sign-in flow and then continue navigation after authentication succeeds.

Use adb to simulate opening a link from the browser.

bash
adb shell am start -a android.intent.action.VIEW \
  -d "https://example.com/products?id=42" \
  com.example.app

This is faster than repeatedly sending yourself emails or chat messages just to tap links. It also makes debugging intent filters much easier.

Common Pitfalls

  • Using a custom scheme when an HTTPS App Link is the better fit. Custom schemes are easier to collide with and less trustworthy to users.
  • Forgetting BROWSABLE in the intent filter. Without it, browser links will not open the activity.
  • Publishing the wrong signing certificate fingerprint in assetlinks.json. Verification fails silently more often than people expect.
  • Assuming every incoming URI is safe. Deep links are external input and should be validated before navigation.
  • Testing only on one Android version. Link handling behavior has changed across releases and OEM builds.

Summary

  • Android opens apps from browser links through deep links and App Links.
  • Custom schemes are simple, but verified HTTPS App Links are usually the production choice.
  • The manifest intent filter defines which URLs the app can receive.
  • 'assetlinks.json is required for domain verification with App Links.'
  • Test with adb and validate all incoming URI data before acting on it.

Course illustration
Course illustration

All Rights Reserved.