diff --git a/health-sdk/example-app/src/main/java/net/gini/android/health/sdk/exampleapp/invoices/ui/InvoicesActivity.kt b/health-sdk/example-app/src/main/java/net/gini/android/health/sdk/exampleapp/invoices/ui/InvoicesActivity.kt index a2429a317..77e38a1d9 100644 --- a/health-sdk/example-app/src/main/java/net/gini/android/health/sdk/exampleapp/invoices/ui/InvoicesActivity.kt +++ b/health-sdk/example-app/src/main/java/net/gini/android/health/sdk/exampleapp/invoices/ui/InvoicesActivity.kt @@ -104,6 +104,7 @@ open class InvoicesActivity : AppCompatActivity() { when (paymentState) { is GiniHealth.PaymentState.Success -> { viewModel.updateDocument() + supportFragmentManager.popBackStack() } else -> {} } diff --git a/health-sdk/sdk/src/main/AndroidManifest.xml b/health-sdk/sdk/src/main/AndroidManifest.xml index 44de3adf8..76c8e1aa5 100644 --- a/health-sdk/sdk/src/main/AndroidManifest.xml +++ b/health-sdk/sdk/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> + diff --git a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt index 4030d1993..b2aeb59a8 100644 --- a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt +++ b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewFragment.kt @@ -1,7 +1,11 @@ package net.gini.android.health.sdk.review +import android.app.PendingIntent import android.content.ActivityNotFoundException +import android.content.BroadcastReceiver +import android.content.Context import android.content.Intent +import android.content.IntentFilter import android.os.Build import android.os.Bundle import android.view.LayoutInflater @@ -128,6 +132,12 @@ class ReviewFragment private constructor( private var documentPageAdapter: DocumentPageAdapter by autoCleared() private var isKeyboardShown = false private var errorSnackbar: Snackbar? = null + private var broadcastReceiver = object: BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + viewModel.setOpenBankStateAfterShareWith() + } + } + override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater { val inflater = super.onGetLayoutInflater(savedInstanceState) @@ -214,6 +224,10 @@ class ReviewFragment private constructor( handlePaymentNextStep(paymentNextStep) } } + launch { + requireActivity().registerReceiver(broadcastReceiver, IntentFilter().also { it.addAction(SHARE_INTENT_FILTER) }, + Context.RECEIVER_NOT_EXPORTED) + } } } } @@ -585,7 +599,7 @@ class ReviewFragment private constructor( flags = Intent.FLAG_GRANT_READ_URI_PERMISSION putExtra(Intent.EXTRA_STREAM, uriForFile) } - startActivity(Intent.createChooser(shareIntent, uriForFile.lastPathSegment)) + startActivity(Intent.createChooser(shareIntent, uriForFile.lastPathSegment, createSharePendingIntent().intentSender)) } private fun handlePaymentNextStep(paymentNextStep: ReviewViewModel.PaymentNextStep) { @@ -609,13 +623,28 @@ class ReviewFragment private constructor( } } + private fun createSharePendingIntent() = PendingIntent.getBroadcast( + requireContext(), CHOOSER_REQUEST_ID, + Intent(requireContext(), ShareWithBroadcastReceiver::class.java), + PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) + override fun onSaveInstanceState(outState: Bundle) { outState.putInt(PAGER_HEIGHT, binding.pager.layoutParams.height) super.onSaveInstanceState(outState) } + override fun onStop() { + requireActivity().unregisterReceiver(broadcastReceiver) + super.onStop() + } + internal companion object { private const val PAGER_HEIGHT = "pager_height" + internal const val SHARE_INTENT_FILTER = "share_intent_filter" + + // This is only required to send when creating the pending intent for the share sheet - not actually used anywhere else + internal const val CHOOSER_REQUEST_ID = 123 fun newInstance( giniHealth: GiniHealth, configuration: ReviewConfiguration = ReviewConfiguration(), @@ -625,4 +654,10 @@ class ReviewFragment private constructor( viewModelFactory: ViewModelProvider.Factory = ReviewViewModel.Factory(giniHealth, configuration, paymentComponent, documentId), ): ReviewFragment = ReviewFragment(listener, paymentComponent, viewModelFactory) } + + internal class ShareWithBroadcastReceiver: BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + context?.sendBroadcast(Intent().also { it.action = SHARE_INTENT_FILTER }) + } + } } diff --git a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewViewModel.kt b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewViewModel.kt index 9c4cff4e4..b3a6a4ebb 100644 --- a/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewViewModel.kt +++ b/health-sdk/sdk/src/main/java/net/gini/android/health/sdk/review/ReviewViewModel.kt @@ -72,6 +72,8 @@ internal class ReviewViewModel( private var openWithCounter: Int = 0 + private val _paymentRequestFlow = MutableStateFlow(null) + val isPaymentButtonEnabled: Flow = combine(giniHealth.openBankState, paymentDetails) { paymentState, paymentDetails -> val noEmptyFields = paymentDetails.recipient.isNotEmpty() && paymentDetails.iban.isNotEmpty() && @@ -305,6 +307,7 @@ internal class ReviewViewModel( giniHealth.setOpenBankState(GiniHealth.PaymentState.Error(throwable), viewModelScope) return@withContext } + _paymentRequestFlow.value = paymentRequest val byteArrayResource = async { giniHealth.giniHealthAPI.documentManager.getPaymentRequestDocument(paymentRequest.id) }.await() when (byteArrayResource) { is Resource.Cancelled -> { @@ -314,7 +317,6 @@ internal class ReviewViewModel( giniHealth.setOpenBankState(GiniHealth.PaymentState.Error(byteArrayResource.exception ?: Exception("Error")), viewModelScope) } is Resource.Success -> { - giniHealth.setOpenBankState(GiniHealth.PaymentState.Success(paymentRequest), viewModelScope) val newFile = externalCacheDir?.createTempPdfFile(byteArrayResource.data, "payment-request") newFile?.let { _paymentNextStep.tryEmit(PaymentNextStep.OpenSharePdf(it)) @@ -325,6 +327,12 @@ internal class ReviewViewModel( } } + internal fun setOpenBankStateAfterShareWith() { + _paymentRequestFlow.value?.let { + giniHealth.setOpenBankState(GiniHealth.PaymentState.Success(it), viewModelScope) + } + } + private fun sendFeedbackAndStartLoading() { giniHealth.setOpenBankState(GiniHealth.PaymentState.Loading, viewModelScope) // TODO: first get the payment request and handle error before proceeding