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>
- 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);
}
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
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>
- 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 scheme | Verified App Link | |
|---|---|---|
| URL form | recipebox://recipe/42 | https://recipebox.example.com/recipe/42 |
| Ownership proof | None — any app can claim the scheme | assetlinks.json hosted on your domain |
| Fallback if unmatched | Nothing opens, or an "open with" prompt | Opens in a browser as a normal web page |
| Trust level | Low | High — 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"