taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

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:
Mcashier/src/main/java/net/taler/cashier/MainActivity.kt | 11+++++++++++
Mmerchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt | 10++++++++++
Mtaler-kotlin-android/src/main/java/net/taler/lib/android/TalerNfcService.kt | 17+++++++++++++++++
Mwallet/src/main/java/net/taler/wallet/MainActivity.kt | 45+++++++++++++++++++++++++++++++--------------
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)