diff options
| author | Adam Soltys <[email protected]> | 2026-09-04 20:53:13 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-04 20:53:13 -0700 |
| commit | e5e375d8ea2f1193ffe01ff02639f002f91f8035 (patch) | |
| tree | dac59b4eace3befeb978263acd749f2822957cfe /android/app/src/main/java | |
| parent | 8d27a5d2c59e0f1824753d59a7326b6b76887bf7 (diff) | |
| download | coinosv3-e5e375d8ea2f1193ffe01ff02639f002f91f8035.tar.gz coinosv3-e5e375d8ea2f1193ffe01ff02639f002f91f8035.zip | |
Android wrapper v1.1: scheme + NFC intents move onto a per-intent trampoline (IntentActivity, noHistory) — a TWA already on screen ignores a new intent delivered to its still-alive launcher, so a second lightning: tap did nothing; the trampoline maps the URI to ?u= form and relaunches the TWA with CLEAR_TOP, which navigates the open app. Verified on a real phone over adb: URL-bar-less fullscreen (assetlinks verified after the site began serving /.well-known/assetlinks.json — the deploy hook's dist/* glob was blind to dot-directories, fixed on cs), lightning: intent lands on Send with the invoice filled, and a second bitcoin: intent fired while the app was open navigated it (BIP-21 parsed, address + amount). NFC NDEF filters ride the trampoline for bolt cards / NDEF tags
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
Diffstat (limited to 'android/app/src/main/java')
| -rw-r--r-- | android/app/src/main/java/io/coinos/app/IntentActivity.java | 35 | ||||
| -rw-r--r-- | android/app/src/main/java/io/coinos/app/LauncherActivity.java | 16 |
2 files changed, 39 insertions, 12 deletions
diff --git a/android/app/src/main/java/io/coinos/app/IntentActivity.java b/android/app/src/main/java/io/coinos/app/IntentActivity.java new file mode 100644 index 0000000..3de1d62 --- /dev/null +++ b/android/app/src/main/java/io/coinos/app/IntentActivity.java @@ -0,0 +1,35 @@ +package io.coinos.app; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +/** + * Trampoline for scheme + NFC intents. A TWA already on screen ignores a + * new intent delivered to its (still-alive) launcher, so a second + * lightning: tap used to do nothing. This activity exists per-intent: + * it maps the URI to the web app's ?u= form and relaunches LauncherActivity + * with CLEAR_TOP — the Chrome activity above it is cleared, the launcher is + * recreated with the new data, and the TWA navigates. Then it's gone. + */ +public class IntentActivity extends android.app.Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Uri url = Uri.parse("https://v3.coinos.io/"); + Uri data = getIntent().getData(); + if (data != null) { + String scheme = data.getScheme(); + if (scheme != null && !scheme.equals("https") && !scheme.equals("http")) { + url = Uri.parse("https://v3.coinos.io/?u=" + Uri.encode(data.toString())); + } else { + url = data; + } + } + Intent i = new Intent(this, LauncherActivity.class); + i.setData(url); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + finish(); + } +} diff --git a/android/app/src/main/java/io/coinos/app/LauncherActivity.java b/android/app/src/main/java/io/coinos/app/LauncherActivity.java index d0b56bb..c3950ac 100644 --- a/android/app/src/main/java/io/coinos/app/LauncherActivity.java +++ b/android/app/src/main/java/io/coinos/app/LauncherActivity.java @@ -3,11 +3,9 @@ package io.coinos.app; import android.net.Uri; /** - * Forwards scheme intents into the web app. A lightning:/bitcoin:/nostr:/ - * lnurl: URI arrives as this activity's data; the web app receives it as - * https://v3.coinos.io/?u=<encoded original URI> and routes it (send form - * for payments, profile for nostr npubs). https links to the site pass - * through untouched, everything else opens the default URL. + * The TWA launcher. Scheme/NFC intents arrive via IntentActivity (the + * trampoline that survives the running-TWA case); this activity only needs + * to honor a full URL handed to it, falling back to the site root. */ public class LauncherActivity extends com.google.androidbrowserhelper.trusted.LauncherActivity { @@ -15,13 +13,7 @@ public class LauncherActivity @Override protected Uri getLaunchingUrl() { Uri data = getIntent().getData(); - if (data != null) { - String scheme = data.getScheme(); - if (scheme != null && !scheme.equals("https") && !scheme.equals("http")) { - return Uri.parse("https://v3.coinos.io/?u=" + Uri.encode(data.toString())); - } - if ("v3.coinos.io".equals(data.getHost())) return data; - } + if (data != null && "v3.coinos.io".equals(data.getHost())) return data; return super.getLaunchingUrl(); } } |
