feat: add nfc step 2 - receive with invoice
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package com.bitcointxoko.gudariwallet
|
||||
|
||||
import android.Manifest
|
||||
import android.app.PendingIntent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.PowerManager
|
||||
@@ -25,6 +28,7 @@ import com.bitcointxoko.gudariwallet.ui.OnboardingScreen
|
||||
import com.bitcointxoko.gudariwallet.ui.WalletScreen
|
||||
import com.bitcointxoko.gudariwallet.ui.WalletViewModel
|
||||
import com.bitcointxoko.gudariwallet.ui.WalletViewModelFactory
|
||||
import com.bitcointxoko.gudariwallet.ui.nfc.NfcViewModel
|
||||
import com.bitcointxoko.gudariwallet.ui.theme.GudariWalletTheme
|
||||
import com.bitcointxoko.gudariwallet.util.NotificationHelper
|
||||
import com.bitcointxoko.gudariwallet.util.IntentUtils
|
||||
@@ -40,13 +44,30 @@ class MainActivity : AppCompatActivity() {
|
||||
WalletViewModelFactory(application)
|
||||
}
|
||||
|
||||
// ── NFC ──────────────────────────────────────────────────────────────────
|
||||
|
||||
val nfcVm: NfcViewModel by viewModels()
|
||||
|
||||
private var nfcAdapter: NfcAdapter? = null
|
||||
|
||||
/** Pending intent used by foreground dispatch — routes tag intents back here. */
|
||||
private val nfcPendingIntent: PendingIntent by lazy {
|
||||
PendingIntent.getActivity(
|
||||
this, 0,
|
||||
Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
|
||||
PendingIntent.FLAG_MUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
// ── Existing state ───────────────────────────────────────────────────────
|
||||
|
||||
// Holds a paymentHash that arrived via notification tap.
|
||||
// WalletScreen observes this and navigates to the detail screen.
|
||||
// MutableState so Compose recomposes when it changes.
|
||||
private val pendingPaymentHash = mutableStateOf<String?>(null)
|
||||
|
||||
// Holds a payment URI that arrived via deep link / intent (BTCPay, external apps).
|
||||
private val pendingPaymentUri = mutableStateOf<String?>(null)
|
||||
private val pendingPaymentUri = mutableStateOf<String?>(null)
|
||||
|
||||
private val requestNotificationPermission =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { /* informational */ }
|
||||
@@ -73,10 +94,14 @@ class MainActivity : AppCompatActivity() {
|
||||
NotificationHelper.createChannels(applicationContext)
|
||||
|
||||
// Read hash from the intent that launched the activity (cold start from notification)
|
||||
pendingPaymentHash.value = intent.getStringExtra(NotificationHelper.EXTRA_PAYMENT_HASH)
|
||||
pendingPaymentHash.value =
|
||||
intent.getStringExtra(NotificationHelper.EXTRA_PAYMENT_HASH)
|
||||
// Read payment URI from the intent that launched the activity (cold start from deep link)
|
||||
pendingPaymentUri.value = IntentUtils.extractPaymentUri(intent)
|
||||
|
||||
// Initialise NFC adapter (null on devices without NFC — handled gracefully)
|
||||
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
|
||||
|
||||
enableEdgeToEdge()
|
||||
|
||||
setContent {
|
||||
@@ -94,6 +119,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
WalletScreen(
|
||||
vm = vm,
|
||||
nfcVm = nfcVm,
|
||||
pendingPaymentHash = pendingPaymentHash,
|
||||
pendingPaymentUri = pendingPaymentUri
|
||||
)
|
||||
@@ -105,26 +131,55 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Called when the activity is already running and a notification is tapped
|
||||
// ── NFC foreground dispatch ───────────────────────────────────────────────
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// Give this activity first pick of all NFC tag intents while foregrounded.
|
||||
// Passing null for techLists and intentFilters means we intercept every tag type.
|
||||
nfcAdapter?.enableForegroundDispatch(
|
||||
this,
|
||||
nfcPendingIntent,
|
||||
null, // intercept all intent filters
|
||||
null // intercept all tech lists
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
nfcAdapter?.disableForegroundDispatch(this)
|
||||
}
|
||||
|
||||
// ── Intent routing ────────────────────────────────────────────────────────
|
||||
|
||||
// Called when the activity is already running and a notification is tapped,
|
||||
// a deep link arrives, or an NFC tag is discovered while foregrounded.
|
||||
// (FLAG_ACTIVITY_SINGLE_TOP prevents a new instance being created)
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
|
||||
// Notification tap → navigate to payment detail
|
||||
val hash = intent.getStringExtra(NotificationHelper.EXTRA_PAYMENT_HASH)
|
||||
if (hash != null) {
|
||||
pendingPaymentHash.value = hash
|
||||
}
|
||||
|
||||
// Deep link / external app URI
|
||||
val uri = IntentUtils.extractPaymentUri(intent)
|
||||
if (uri != null) {
|
||||
pendingPaymentUri.value = uri
|
||||
}
|
||||
|
||||
// NFC tag discovered → hand off to NfcViewModel for reading
|
||||
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||
if (tag != null) {
|
||||
nfcVm.onTagDiscovered(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ── Permission / battery helpers (unchanged) ──────────────────────────────
|
||||
|
||||
private fun requestNotificationPermissionIfNeeded() {
|
||||
@@ -154,9 +209,10 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun openBatterySettings() {
|
||||
val appDetailsIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||
data = "package:$packageName".toUri()
|
||||
}
|
||||
val appDetailsIntent =
|
||||
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||
data = "package:$packageName".toUri()
|
||||
}
|
||||
if (tryStartActivity(appDetailsIntent)) return
|
||||
tryStartActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user