add biometrics to confirm digalogbox
All checks were successful
Auto Tag on Version Change / check-version (push) Successful in 2s
All checks were successful
Auto Tag on Version Change / check-version (push) Successful in 2s
This commit is contained in:
@@ -211,6 +211,7 @@ class HomeActivity : AppCompatActivity() {
|
||||
R.id.nav_settings -> show(SettingsFragment())
|
||||
else -> Toast.makeText(this, R.string.work_in_progress, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
binding.navigationView.setCheckedItem(itemId)
|
||||
val bottomNavIds = setOf(R.id.nav_dashboard, R.id.nav_accounts, R.id.nav_contacts, R.id.nav_transfer, R.id.nav_more)
|
||||
if (binding.bottomNavigation.visibility == View.VISIBLE && itemId in bottomNavIds) {
|
||||
suppressBottomNavCallback = true
|
||||
|
||||
@@ -17,6 +17,7 @@ class MoreFragment : Fragment() {
|
||||
private data class NavItem(val id: Int, @DrawableRes val icon: Int, @StringRes val title: Int)
|
||||
|
||||
private val items = listOf(
|
||||
NavItem(R.id.nav_pay_mv_qr, R.drawable.ic_qr_scan, R.string.pay_mv_qr),
|
||||
NavItem(R.id.nav_activities, R.drawable.ic_nav_activities, R.string.nav_activities),
|
||||
NavItem(R.id.nav_transfer_history, R.drawable.ic_nav_transfer_history, R.string.nav_transfer_history),
|
||||
NavItem(R.id.nav_finances, R.drawable.ic_nav_finances, R.string.nav_finances),
|
||||
|
||||
@@ -36,9 +36,23 @@ class SettingsSecurityFragment : Fragment() {
|
||||
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS
|
||||
if (canUseBiometrics) {
|
||||
binding.rowBiometrics.visibility = View.VISIBLE
|
||||
binding.switchBiometrics.isChecked = prefs.getBoolean("biometrics_enabled", false)
|
||||
|
||||
val unlockEnabled = prefs.getBoolean("biometrics_enabled", false)
|
||||
binding.switchBiometrics.isChecked = unlockEnabled
|
||||
binding.switchBiometricsTransfer.isChecked = prefs.getBoolean("biometrics_transfer_confirm", false)
|
||||
binding.switchBiometricsTransfer.isEnabled = unlockEnabled
|
||||
|
||||
binding.switchBiometrics.setOnCheckedChangeListener { _, isChecked ->
|
||||
prefs.edit().putBoolean("biometrics_enabled", isChecked).apply()
|
||||
binding.switchBiometricsTransfer.isEnabled = isChecked
|
||||
if (!isChecked) {
|
||||
binding.switchBiometricsTransfer.isChecked = false
|
||||
prefs.edit().putBoolean("biometrics_transfer_confirm", false).apply()
|
||||
}
|
||||
}
|
||||
|
||||
binding.switchBiometricsTransfer.setOnCheckedChangeListener { _, isChecked ->
|
||||
prefs.edit().putBoolean("biometrics_transfer_confirm", isChecked).apply()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
@@ -562,29 +565,31 @@ class TransferFragment : Fragment() {
|
||||
|
||||
val mainMsg = "Send $currency $amountStr to $destDisplay?\n\nFrom: ${src.accountBriefName} · ${src.accountNumber}"
|
||||
|
||||
val dialogBuilder = AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.transfer)
|
||||
.setPositiveButton(R.string.transfer_confirm) { _, _ ->
|
||||
binding.btnTransfer.isEnabled = false
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val (ok, msg, receipt) = withContext(Dispatchers.IO) {
|
||||
if (!isSrcBml) {
|
||||
doMibTransfer(src, resolvedAccountNumber, resolvedRecipientName, destDisplay, amountStr, remarks, bankNameCapture)
|
||||
} else {
|
||||
doBmlTransfer(src, resolvedAccountNumber, destDisplay, amount, amountStr, remarks, isSrcCard, isDestMib, currency, allAccounts, allContacts)
|
||||
}
|
||||
}
|
||||
binding.btnTransfer.isEnabled = true
|
||||
if (ok && receipt != null) {
|
||||
clearForm()
|
||||
val activity = requireActivity() as HomeActivity
|
||||
activity.refreshBalances(src)
|
||||
activity.showWithBackStack(TransferReceiptFragment.newInstance(receipt, capturedToAvatar))
|
||||
} else if (!ok) {
|
||||
Toast.makeText(requireContext(), msg, Toast.LENGTH_LONG).show()
|
||||
val doTransfer: () -> Unit = {
|
||||
binding.btnTransfer.isEnabled = false
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val (ok, msg, receipt) = withContext(Dispatchers.IO) {
|
||||
if (!isSrcBml) {
|
||||
doMibTransfer(src, resolvedAccountNumber, resolvedRecipientName, destDisplay, amountStr, remarks, bankNameCapture)
|
||||
} else {
|
||||
doBmlTransfer(src, resolvedAccountNumber, destDisplay, amount, amountStr, remarks, isSrcCard, isDestMib, currency, allAccounts, allContacts)
|
||||
}
|
||||
}
|
||||
binding.btnTransfer.isEnabled = true
|
||||
if (ok && receipt != null) {
|
||||
clearForm()
|
||||
val activity = requireActivity() as HomeActivity
|
||||
activity.refreshBalances(src)
|
||||
activity.showWithBackStack(TransferReceiptFragment.newInstance(receipt, capturedToAvatar))
|
||||
} else if (!ok) {
|
||||
Toast.makeText(requireContext(), msg, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dialogBuilder = AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.transfer)
|
||||
.setPositiveButton(R.string.transfer_confirm) { _, _ -> doTransfer() }
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
|
||||
if (isUsdToMvr) {
|
||||
@@ -606,7 +611,39 @@ class TransferFragment : Fragment() {
|
||||
} else {
|
||||
dialogBuilder.setMessage(mainMsg)
|
||||
}
|
||||
dialogBuilder.show()
|
||||
|
||||
val dialog = dialogBuilder.show()
|
||||
|
||||
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||
val biometricTransferConfirm = prefs.getBoolean("biometrics_transfer_confirm", false)
|
||||
val canAuth = BiometricManager.from(requireContext())
|
||||
.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS
|
||||
if (biometricTransferConfirm && canAuth) {
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||
val prompt = BiometricPrompt(this, ContextCompat.getMainExecutor(requireContext()),
|
||||
object : BiometricPrompt.AuthenticationCallback() {
|
||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||
dialog.dismiss()
|
||||
doTransfer()
|
||||
}
|
||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||
if (errorCode != BiometricPrompt.ERROR_CANCELED &&
|
||||
errorCode != BiometricPrompt.ERROR_USER_CANCELED &&
|
||||
errorCode != BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
|
||||
Toast.makeText(requireContext(), errString, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
override fun onAuthenticationFailed() { /* keep dialog open */ }
|
||||
})
|
||||
prompt.authenticate(
|
||||
BiometricPrompt.PromptInfo.Builder()
|
||||
.setTitle(getString(R.string.biometric_transfer_title))
|
||||
.setSubtitle("$currency $amountStr → $destDisplay")
|
||||
.setNegativeButtonText(getString(android.R.string.cancel))
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun doMibTransfer(
|
||||
|
||||
@@ -30,23 +30,60 @@
|
||||
android:id="@+id/rowBiometrics"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="16dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/settings_biometrics"
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||
android:textColor="?attr/colorOnSurface" />
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switchBiometrics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/settings_biometrics"
|
||||
android:textAppearance="?attr/textAppearanceTitleSmall"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/settings_biometrics_unlock"
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||
android:textColor="?attr/colorOnSurface" />
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switchBiometrics"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/settings_biometrics_transfer"
|
||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||
android:textColor="?attr/colorOnSurface" />
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switchBiometricsTransfer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -5,12 +5,18 @@
|
||||
<item android:id="@+id/nav_dashboard"
|
||||
android:icon="@drawable/ic_nav_dashboard"
|
||||
android:title="@string/nav_dashboard" />
|
||||
<item android:id="@+id/nav_accounts"
|
||||
android:icon="@drawable/ic_nav_accounts"
|
||||
android:title="@string/nav_accounts" />
|
||||
</group>
|
||||
|
||||
<group android:id="@+id/group_finance" android:checkableBehavior="single">
|
||||
<item android:id="@+id/nav_accounts"
|
||||
android:icon="@drawable/ic_nav_accounts"
|
||||
android:title="@string/nav_accounts" />
|
||||
<item android:id="@+id/nav_transfer"
|
||||
android:icon="@drawable/ic_send"
|
||||
android:title="@string/transfer" />
|
||||
<item android:id="@+id/nav_pay_mv_qr"
|
||||
android:icon="@drawable/ic_qr_scan"
|
||||
android:title="@string/pay_mv_qr" />
|
||||
<item android:id="@+id/nav_contacts"
|
||||
android:icon="@drawable/ic_contacts"
|
||||
android:title="@string/nav_contacts" />
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/nav_pay_mv_qr"
|
||||
android:icon="@drawable/ic_qr_scan"
|
||||
android:title="@string/pay_mv_qr" />
|
||||
<item android:id="@+id/nav_activities"
|
||||
android:icon="@drawable/ic_nav_activities"
|
||||
android:title="@string/nav_activities" />
|
||||
|
||||
@@ -103,7 +103,10 @@
|
||||
<!-- Settings -->
|
||||
<string name="settings_security">Security</string>
|
||||
<string name="settings_change_lock">Change PIN / Pattern</string>
|
||||
<string name="settings_biometrics">Use Biometrics</string>
|
||||
<string name="settings_biometrics">Use biometrics</string>
|
||||
<string name="settings_biometrics_unlock">To unlock app</string>
|
||||
<string name="settings_biometrics_transfer">Confirm transfer</string>
|
||||
<string name="biometric_transfer_title">Confirm Transfer</string>
|
||||
<string name="settings_autolock">Auto-lock</string>
|
||||
<string name="autolock_off">Off</string>
|
||||
<string name="autolock_30s">30s</string>
|
||||
|
||||
Reference in New Issue
Block a user