feat(android): QR code scanner for Send address field

Camera2 + ZXing.Net 0.16.9 activity (ScannerActivity) that captures JPEG
frames at ~2.5 fps and decodes QR codes without Xamarin dependencies.
Result is returned to MainActivity via OnActivityResult/TaskCompletionSource.
PlatformServices.ScanQrAsync seam wires Android head to shared App layer;
ScanQrCommand in the Send ViewModel strips BIP21 URI scheme/query parameters.
CAMERA permission and uses-feature added to AndroidManifest.
This commit is contained in:
2026-06-15 10:19:24 +02:00
parent 8476eeb247
commit bfee0dde03
8 changed files with 292 additions and 5 deletions
+1
View File
@@ -183,6 +183,7 @@ public sealed class Loc
["send.all"] = ["Invia tutto", "Send all", "Enviar todo", "Tout envoyer", "Enviar tudo", "Alles senden"],
["send.feerate"] = ["fee sat/vB:", "fee sat/vB:", "tarifa sat/vB:", "frais sat/vB :", "taxa sat/vB:", "Gebühr sat/vB:"],
["send.prepare"] = ["Prepara transazione", "Prepare transaction", "Preparar transacción", "Préparer la transaction", "Preparar transação", "Transaktion vorbereiten"],
["send.scan"] = ["Scansiona QR", "Scan QR", "Escanear QR", "Scanner QR", "Escanear QR", "QR scannen"],
["send.confirm"] = ["CONFERMA E TRASMETTI", "CONFIRM AND BROADCAST", "CONFIRMAR Y TRANSMITIR", "CONFIRMER ET DIFFUSER", "CONFIRMAR E TRANSMITIR", "BESTÄTIGEN UND SENDEN"],
// Stato connessione
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Threading.Tasks;
namespace PalladiumWallet.App.Services;
/// <summary>
/// Seam per servizi specifici della piattaforma (Android/desktop).
/// Il head Android imposta i delegate in OnCreate; desktop li lascia null.
/// </summary>
public static class PlatformServices
{
/// <summary>
/// Apre lo scanner QR nativo e restituisce il testo raw del codice,
/// oppure null se l'utente annulla o lo scanner non è disponibile.
/// </summary>
public static Func<Task<string?>>? ScanQrAsync { get; set; }
}
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NBitcoin;
using PalladiumWallet.App.Services;
using PalladiumWallet.Core.Chain;
using PalladiumWallet.Core.Net;
using PalladiumWallet.Core.Wallet;
@@ -29,6 +30,18 @@ public partial class MainWindowViewModel
[ObservableProperty]
private bool hasPendingSend;
[RelayCommand]
private async Task ScanQr()
{
if (PlatformServices.ScanQrAsync is not { } scan) return;
var raw = await scan();
if (string.IsNullOrWhiteSpace(raw)) return;
// Gestisce URI tipo "palladium:ADDRESS?amount=X" estraendo solo l'indirizzo
var address = raw.Contains(':') ? raw.Split(':')[1] : raw;
if (address.Contains('?')) address = address.Split('?')[0];
SendTo = address.Trim();
}
[RelayCommand]
private async Task PrepareSend()
{