commit 1fb8e795fa2e5b62e58688e2b81fa97bdf71cd58
parent 3c1c86ba64acdd185b7e5612f8806c127cf2ca51
Author: Iván Ávalos <avalos@disroot.org>
Date: Tue, 16 Jul 2024 11:47:16 -0600
Fix NFC intent handling and register apps as default handlers on foreground
Diffstat:
4 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/cashier/src/main/java/net/taler/cashier/MainActivity.kt b/cashier/src/main/java/net/taler/cashier/MainActivity.kt
@@ -26,6 +26,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import net.taler.cashier.databinding.ActivityMainBinding
+import net.taler.lib.android.TalerNfcService
class MainActivity : AppCompatActivity() {
@@ -52,6 +53,16 @@ class MainActivity : AppCompatActivity() {
}
}
+ override fun onResume() {
+ super.onResume()
+ TalerNfcService.setDefaultHandler(this)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ TalerNfcService.unsetDefaultHandler(this)
+ }
+
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (!configManager.hasConfig() && nav.currentDestination?.id == R.id.configFragment) {
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt
@@ -83,6 +83,16 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
}
}
+ override fun onResume() {
+ super.onResume()
+ TalerNfcService.setDefaultHandler(this)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ TalerNfcService.unsetDefaultHandler(this)
+ }
+
override fun onNavigationItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.nav_order -> nav.navigate(R.id.action_global_order)
diff --git a/taler-kotlin-android/src/main/java/net/taler/lib/android/TalerNfcService.kt b/taler-kotlin-android/src/main/java/net/taler/lib/android/TalerNfcService.kt
@@ -18,11 +18,13 @@ package net.taler.lib.android
import android.app.Activity
import android.app.Service
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter.getDefaultAdapter
+import android.nfc.cardemulation.CardEmulation
import android.nfc.cardemulation.HostApduService
import android.os.Bundle
import android.util.Log
@@ -299,6 +301,21 @@ class TalerNfcService : HostApduService() {
return getDefaultAdapter(context) != null
}
+ fun setDefaultHandler(activity: Activity) {
+ val adapter = getDefaultAdapter(activity)
+ val emulation = CardEmulation.getInstance(adapter)
+ val cn = ComponentName(activity.packageName, TalerNfcService::class.java.canonicalName!!)
+ Log.d(TAG, "setting $cn as default NFC handler")
+ emulation.setPreferredService(activity, cn)
+ }
+
+ fun unsetDefaultHandler(activity: Activity) {
+ val adapter = getDefaultAdapter(activity)
+ val emulation = CardEmulation.getInstance(adapter)
+ Log.d(TAG, "unsetting ${activity.packageName} as default NFC handler")
+ emulation.unsetPreferredService(activity)
+ }
+
fun setUri(activity: Activity, uri: String) {
val intent = Intent(activity, TalerNfcService::class.java)
intent.putExtra("uri", uri)
diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
@@ -21,6 +21,7 @@ import android.content.Intent
import android.content.Intent.ACTION_VIEW
import android.nfc.NdefMessage
import android.nfc.NfcAdapter
+import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
@@ -107,7 +108,7 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener,
// ui.navView.menu.findItem(R.id.nav_dev).isVisible = enabled
// }
- handleIntents()
+ handleIntents(intent)
model.transactionManager.selectedTransaction.observe(this) { tx ->
TalerNfcService.clearUri(this)
@@ -151,24 +152,30 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener,
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
- handleIntents()
+ handleIntents(intent)
}
- private fun handleIntents() {
- if (intent?.action == ACTION_VIEW) intent.dataString?.let { uri ->
+ private fun handleIntents(intent: Intent?) {
+ if (intent == null) return
+
+ if (intent.action == ACTION_VIEW) intent.dataString?.let { uri ->
handleTalerUri(uri, "intent")
}
- if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent?.action) {
- intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages ->
- val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage }
-
- messages.forEach { message ->
- message.records?.forEach { record ->
- record.toUri()?.let { uri ->
- Log.d(TAG, "URI read from NFC tag: $uri")
- handleTalerUri(uri.toString(), "nfc")
- }
+ if (intent.action == NfcAdapter.ACTION_NDEF_DISCOVERED) {
+ val messages: Array<NdefMessage> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, NdefMessage::class.java)
+ } else {
+ @Suppress("DEPRECATION")
+ intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.let { rawMessages ->
+ rawMessages.map { it as NdefMessage }
+ }?.toTypedArray()
+ } ?: return
+
+ messages.forEach { message ->
+ message.records?.forEach { record ->
+ record.toUri()?.let { uri ->
+ handleTalerUri(uri.toString(), "nfc")
}
}
}
@@ -235,6 +242,16 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener,
return true
}
+ override fun onResume() {
+ super.onResume()
+ TalerNfcService.setDefaultHandler(this)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ TalerNfcService.unsetDefaultHandler(this)
+ }
+
override fun onDestroy() {
super.onDestroy()
TalerNfcService.clearUri(this)