Deep Links & App Links (Java)

A normal launcher tap opens RecipeBox to its main screen. A deep link does better — it's a URI that opens a specific screen directly. Tap a link to recipebox://recipe/42 from a text message, a notification, or a website, and RecipeBox opens straight to recipe id 42's detail screen, skipping the main list entirely.

Custom URI Scheme Deep Links

The simplest form uses a custom scheme you invent — here, recipebox:// — declared as an <intent-filter> on the Activity that should handle it:

<activity android:name=".RecipeDetailActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="recipebox" android:host="recipe" />
    </intent-filter>
</activity>
Explanation:
  • android:scheme="recipebox" is the part before :// — any app could register the same scheme, since it's not tied to anything you own.
  • BROWSABLE lets a link be triggered from a browser or another app, not only from within RecipeBox itself.
  • A URI like recipebox://recipe/42 matches this filter — recipe is the host, 42 is a path segment carrying the recipe id.

Reading the Deep Link Data

Inside RecipeDetailActivity, pull the recipe id back out of the incoming Intent using getIntent().getData():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recipe_detail);

    Uri data = getIntent().getData();
    int recipeId;

    if (data != null) {
        // recipebox://recipe/42 -> last path segment is "42"
        recipeId = Integer.parseInt(data.getLastPathSegment());
    } else {
        // Opened normally, e.g. from a list click, via an extra instead
        recipeId = getIntent().getIntExtra("recipe_id", -1);
    }

    loadRecipe(recipeId);
}
Always handle both cases: this Activity might be opened from a deep link (data is set) or normally from inside the app (a plain Intent extra, as used back in the notification tap example).

App Links: A Stronger, Verified Version

The problem with recipebox:// is that any app can declare the same custom scheme — there's no ownership check. App Links solve this by using real https:// URLs on a domain you actually control, verified through Android's Digital Asset Links system.

You host a small file at https://recipebox.example.com/.well-known/assetlinks.json that lists your app's package name and signing certificate fingerprint. Android checks that file against your app's own manifest declaration — if they match, it proves you own both the website and the app, so Android opens RecipeBox directly instead of falling back to a browser for matching links.

Custom Scheme

recipebox://recipe/42 — any app can claim this scheme

vs

App Link

https://recipebox.example.com/recipe/42 — verified via assetlinks.json

Declaring a Verified App Link

<activity android:name=".RecipeDetailActivity"
    android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https"
              android:host="recipebox.example.com"
              android:pathPrefix="/recipe" />
    </intent-filter>
</activity>
Explanation:
  • android:autoVerify="true" tells the system to check assetlinks.json on the declared host before treating this as a verified App Link.
  • Once verified, tapping https://recipebox.example.com/recipe/42 anywhere — a chat app, an email, search results — opens RecipeBox with no "open with" chooser dialog.
  • The same getIntent().getData() code from earlier still reads the incoming URI; only the manifest declaration and verification changed.
Custom URI schemeVerified App Link
URL formrecipebox://recipe/42https://recipebox.example.com/recipe/42
Ownership proofNone — any app can claim the schemeassetlinks.json hosted on your domain
Fallback if unmatchedNothing opens, or an "open with" promptOpens in a browser as a normal web page
Trust levelLowHigh — verified by the OS

Testing a Deep Link from the Command Line

Rather than tapping a link on a physical device every time, adb can trigger a deep link directly and print timing/result info:

adb shell am start -W -a android.intent.action.VIEW -d "recipebox://recipe/42"
Watch the command's output: a Status: ok line confirms RecipeBox handled it, and the reported TotalTime shows how long the app took to launch and reach that screen — useful for catching a slow cold start on the recipe detail path.
RecipeBox can now be opened from outside itself in several ways — a shortcut, a widget, or a link. Next, In-App Updates covers keeping the app itself current once users are already inside it.