diff --git a/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcManager.kt b/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcManager.kt index ee5e3ab3..f07c662c 100644 --- a/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcManager.kt +++ b/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcManager.kt @@ -36,6 +36,7 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife private val onTagDiscoveredListeners: MutableList = mutableListOf() private var activity: Activity? = null private var nfcAdapter: NfcAdapter? = null + private var isReaderModeEnabled: Boolean = false private val mBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { @@ -62,6 +63,14 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife onTagDiscoveredListeners.remove(listener) } + override fun onForceEnableReadingMode() { + enableReaderModeIfNfcEnabled() + } + + override fun onForceDisableReadingMode() { + disableReaderMode() + } + fun setCurrentActivity(activity: Activity) { this.activity = activity nfcAdapter = NfcAdapter.getDefaultAdapter(activity) @@ -75,29 +84,15 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife override fun onStart(owner: LifecycleOwner) { reader.listener = this - } - - override fun onResume(owner: LifecycleOwner) { - super.onResume(owner) enableReaderModeIfNfcEnabled() } - override fun onPause(owner: LifecycleOwner) { - super.onPause(owner) - disableReaderMode() - } - override fun onStop(owner: LifecycleOwner) { + disableReaderMode() reader.stopSession(true) reader.listener = null } - override fun onStartSession() { - disableReaderMode() - Thread.sleep(DELAY_BEFORE_ENABLE) - enableReaderModeIfNfcEnabled() - } - override fun onDestroy(owner: LifecycleOwner) { activity?.unregisterReceiver(mBroadcastReceiver) activity = null @@ -113,16 +108,22 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife } private fun enableReaderMode() { - Log.nfc { "enableReaderMode" } + Log.nfc { "enableReaderMode isReaderModeEnabled $isReaderModeEnabled" } if (activity?.isDestroyed == false) { + if (isReaderModeEnabled) { + disableReaderMode() + Thread.sleep(DELAY_BEFORE_ENABLE) + } nfcAdapter?.enableReaderMode(activity, this, READER_FLAGS, Bundle()) + isReaderModeEnabled = true } } private fun disableReaderMode() { - Log.nfc { "disableReaderMode" } - if (activity?.isDestroyed == false) { + Log.nfc { "disableReaderMode $isReaderModeEnabled" } + if (activity?.isDestroyed == false && isReaderModeEnabled) { nfcAdapter?.disableReaderMode(activity) + isReaderModeEnabled = false } } @@ -144,6 +145,6 @@ class NfcManager : NfcAdapter.ReaderCallback, ReadingActiveListener, DefaultLife NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS const val IGNORE_DEBOUNCE_MS = 1_500 - private const val DELAY_BEFORE_ENABLE = 200L + private const val DELAY_BEFORE_ENABLE = 300L } } diff --git a/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcReader.kt b/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcReader.kt index fe975556..c3695ac1 100644 --- a/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcReader.kt +++ b/tangem-sdk-android/src/main/java/com/tangem/sdk/nfc/NfcReader.kt @@ -48,7 +48,6 @@ class NfcReader : CardReader { scope?.launchWithLock(readerMutex) { Log.nfc { "start NFC session, thread ${Thread.currentThread().id}" } nfcTag = null - listener?.onStartSession() listener?.readingIsActive = true } } @@ -63,7 +62,6 @@ class NfcReader : CardReader { override fun resumeSession() { scope?.launchWithLock(readerMutex) { Log.nfc { "resume NFC session, thread ${Thread.currentThread().id}" } - listener?.onStartSession() listener?.readingIsActive = true } } @@ -76,14 +74,11 @@ class NfcReader : CardReader { } IsoDep.get(tag)?.let { isoDep -> connect( - isoDep, + isoDep = isoDep, onSuccess = { nfcTag = NfcTag(TagType.Nfc, isoDep) }, - onError = { - nfcTag = null - }, - ) + ) { } } } } @@ -209,6 +204,16 @@ class NfcReader : CardReader { } } + override fun forceEnableReaderMode() { + Log.nfc { "forceEnableReaderMode" } + listener?.onForceEnableReadingMode() + } + + override fun forceDisableReaderMode() { + Log.nfc { "forceDisableReaderMode" } + listener?.onForceDisableReadingMode() + } + private fun CoroutineScope.launchWithLock(mutex: Mutex, action: suspend () -> Unit) { this.launch { mutex.withLock(null) { diff --git a/tangem-sdk-core/src/main/java/com/tangem/TangemSdk.kt b/tangem-sdk-core/src/main/java/com/tangem/TangemSdk.kt index 28cb613f..6e560d94 100644 --- a/tangem-sdk-core/src/main/java/com/tangem/TangemSdk.kt +++ b/tangem-sdk-core/src/main/java/com/tangem/TangemSdk.kt @@ -78,6 +78,24 @@ class TangemSdk( CryptoUtils.initCrypto() } + /** + * This method enables [NfcAdapter] reader mode if it was disabled + * Use carefully, by default sdk enables reader mode automatically + * but some devices could disable it in some cases out of lifecycle + * For example: launch qr code scanner on Samsung + */ + fun forceEnableReaderMode() { + reader.forceEnableReaderMode() + } + + /** + * This method disables [NfcAdapter] reader mode if it was enabled + * Don't forget call [forceEnableReaderMode] after this + */ + fun forceDisableReaderMode() { + reader.forceDisableReaderMode() + } + // region Card operations /** * This method launches a [ScanTask] on a new thread. diff --git a/tangem-sdk-core/src/main/java/com/tangem/common/nfc/CardReader.kt b/tangem-sdk-core/src/main/java/com/tangem/common/nfc/CardReader.kt index 180fd80c..d2be56c3 100644 --- a/tangem-sdk-core/src/main/java/com/tangem/common/nfc/CardReader.kt +++ b/tangem-sdk-core/src/main/java/com/tangem/common/nfc/CardReader.kt @@ -54,10 +54,23 @@ interface CardReader { fun resumeSession() fun readSlixTag(callback: CompletionCallback) + + /** + * Some devices (Samsung) could disable reader mode when open camera inside app, + * after this we should call [forceEnableReaderMode] manually + */ + fun forceEnableReaderMode() + + /** + * Use for some cases when you need to [forceDisableReaderMode] manually, + * don't forget call [forceEnableReaderMode] after this + */ + fun forceDisableReaderMode() } interface ReadingActiveListener { var readingIsActive: Boolean - fun onStartSession() + fun onForceEnableReadingMode() + fun onForceDisableReadingMode() }