This commit is contained in:
@@ -32,7 +32,10 @@ import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -162,9 +165,21 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
).also { mfaisaHandler = it }
|
||||
|
||||
private val qrLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
val raw = result.data?.getStringExtra(QrScannerActivity.EXTRA_QR_CONTENT) ?: return@registerForActivityResult
|
||||
// Registered manually against the activity registry in onViewCreated rather than with a
|
||||
// registerForActivityResult() field initializer: HomeActivity caches one TransferFragment
|
||||
// instance (cachedTransferFragment) and re-shows it after a replace(). A field initializer
|
||||
// runs only once, so once that instance was destroyed the launcher stayed unregistered and
|
||||
// launching it threw. Keying off viewLifecycleOwner re-registers on every view creation.
|
||||
private val qrLauncherKey = "transfer_qr_" + UUID.randomUUID()
|
||||
private var qrLauncher: ActivityResultLauncher<Intent>? = null
|
||||
|
||||
private fun launchQrScanner() {
|
||||
qrLauncher?.launch(Intent(requireContext(), QrScannerActivity::class.java))
|
||||
}
|
||||
|
||||
private fun onQrScanned(result: ActivityResult) {
|
||||
if (result.resultCode != Activity.RESULT_OK) return
|
||||
val raw = result.data?.getStringExtra(QrScannerActivity.EXTRA_QR_CONTENT) ?: return
|
||||
|
||||
// BML card/gateway QR — hand off to dedicated payment screen
|
||||
val bmlUrl = PaymvQrParser.extractBmlGatewayUrl(raw)
|
||||
@@ -173,7 +188,7 @@ class TransferFragment : Fragment() {
|
||||
it.profileType == "BML_PREPAID" || it.profileType == "BML_CREDIT" || it.profileType == "BML_DEBIT"
|
||||
}
|
||||
(requireActivity() as HomeActivity).navigateTo(R.id.nav_transfer, TransferFragment.newInstanceFromBmlQr(bmlUrl ?: raw, fromCard?.accountNumber))
|
||||
return@registerForActivityResult
|
||||
return
|
||||
}
|
||||
|
||||
// M-Faisa merchant QR — content is just the numeric qrCodeId. Only attempt the lookup
|
||||
@@ -184,13 +199,13 @@ class TransferFragment : Fragment() {
|
||||
if (trimmedRaw.length in 8..16 && trimmedRaw.all { it.isDigit() } &&
|
||||
app.mfaisaSessions.isNotEmpty()) {
|
||||
lookupMfaisaQrMerchant(trimmedRaw)
|
||||
return@registerForActivityResult
|
||||
return
|
||||
}
|
||||
|
||||
val qr = PaymvQrParser.parse(raw)
|
||||
if (qr == null || qr.accountNumber == null) {
|
||||
Toast.makeText(requireContext(), R.string.transfer_qr_invalid, Toast.LENGTH_SHORT).show()
|
||||
return@registerForActivityResult
|
||||
return
|
||||
}
|
||||
|
||||
// Cards can't pay PayMV QR — fall back to default account or clear selection
|
||||
@@ -287,6 +302,10 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
qrLauncher = requireActivity().activityResultRegistry.register(
|
||||
qrLauncherKey, viewLifecycleOwner, ActivityResultContracts.StartActivityForResult()
|
||||
) { onQrScanned(it) }
|
||||
|
||||
setupFromDropdown()
|
||||
setupAccountLookup()
|
||||
|
||||
@@ -340,7 +359,7 @@ class TransferFragment : Fragment() {
|
||||
}
|
||||
|
||||
binding.btnScanQr.setOnClickListener {
|
||||
qrLauncher.launch(Intent(requireContext(), QrScannerActivity::class.java))
|
||||
launchQrScanner()
|
||||
}
|
||||
|
||||
viewModel.connectivityErrors.observe(viewLifecycleOwner) { updateTransferButton() }
|
||||
@@ -369,7 +388,7 @@ class TransferFragment : Fragment() {
|
||||
arguments?.getString(ARG_BML_QR_URL)?.let { bmlHandler().lookupQrMerchant(it) }
|
||||
|
||||
if (arguments?.getBoolean(ARG_AUTO_SCAN, false) == true) {
|
||||
qrLauncher.launch(Intent(requireContext(), QrScannerActivity::class.java))
|
||||
launchQrScanner()
|
||||
}
|
||||
|
||||
// Restore form state when view is recreated on the cached no-args instance
|
||||
@@ -2002,6 +2021,8 @@ class TransferFragment : Fragment() {
|
||||
bmlHandler = null
|
||||
mfaisaHandler?.clearState()
|
||||
mfaisaHandler = null
|
||||
// Unregistered automatically with viewLifecycleOwner; drop the stale handle.
|
||||
qrLauncher = null
|
||||
_binding = null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user