aboutsummaryrefslogtreecommitdiffstats
path: root/android/app/src/main/java/io
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-04 20:53:13 -0700
committerAdam Soltys <[email protected]>2026-09-04 20:53:13 -0700
commite5e375d8ea2f1193ffe01ff02639f002f91f8035 (patch)
treedac59b4eace3befeb978263acd749f2822957cfe /android/app/src/main/java/io
parent8d27a5d2c59e0f1824753d59a7326b6b76887bf7 (diff)
downloadcoinosv3-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/io')
-rw-r--r--android/app/src/main/java/io/coinos/app/IntentActivity.java35
-rw-r--r--android/app/src/main/java/io/coinos/app/LauncherActivity.java16
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();
}
}