Show dedicated UI with instruction when NFC is lost

This commit is contained in:
mimi89999
2025-12-23 19:24:47 +01:00
parent 160695a0aa
commit 7b89b93f4c
5 changed files with 34 additions and 6 deletions

View File

@@ -3,6 +3,7 @@ package pl.lebihan.authnkey
import android.animation.ObjectAnimator
import android.content.Context
import android.content.DialogInterface
import android.content.res.ColorStateList
import android.os.Bundle
import android.text.InputType
import android.view.LayoutInflater
@@ -14,6 +15,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -33,6 +35,7 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
PIN,
ACCOUNT_SELECT,
SUCCESS,
TAG_LOST,
ERROR
}
@@ -221,20 +224,28 @@ class CredentialBottomSheet : BottomSheetDialogFragment() {
State.PIN -> R.drawable.lock_24
State.ACCOUNT_SELECT -> R.drawable.account_circle_24
State.SUCCESS -> R.drawable.check_circle_24
State.TAG_LOST -> R.drawable.sensors_24
State.ERROR -> R.drawable.error_24
}
iconStatus.setImageResource(iconRes)
iconBackground.backgroundTintList = null
when (state) {
State.WAITING, State.TOUCH -> startPulse()
State.TAG_LOST -> {
iconBackground.backgroundTintList = ColorStateList.valueOf(
ContextCompat.getColor(requireContext(), R.color.warning_container)
)
startPulse(750)
}
else -> {}
}
}
private fun startPulse() {
private fun startPulse(durationMs: Long = 1000) {
pulseAnimator = ObjectAnimator.ofFloat(iconBackground, View.ALPHA, 1f, 0.3f).apply {
duration = 1000
duration = durationMs
repeatCount = ObjectAnimator.INFINITE
repeatMode = ObjectAnimator.REVERSE
interpolator = AccelerateDecelerateInterpolator()

View File

@@ -387,9 +387,14 @@ class CredentialProviderActivity : AppCompatActivity() {
} catch (e: Exception) {
Log.e(TAG, "NFC error", e)
setInstruction(getString(R.string.error_retry_format, e.toUserMessage(this@CredentialProviderActivity)))
setState(CredentialBottomSheet.State.ERROR)
showProgress(false)
if (e is android.nfc.TagLostException) {
setInstruction(getString(R.string.instruction_tag_lost))
setState(CredentialBottomSheet.State.TAG_LOST)
} else {
setInstruction(getString(R.string.error_retry_format, e.toUserMessage(this@CredentialProviderActivity)))
setState(CredentialBottomSheet.State.ERROR)
}
}
}
}
@@ -1074,8 +1079,13 @@ class CredentialProviderActivity : AppCompatActivity() {
private fun handleError(e: Exception) {
runOnUiThread {
showProgress(false)
setInstruction(getString(R.string.error_format, e.toUserMessage(this)))
setState(CredentialBottomSheet.State.ERROR)
if (e is android.nfc.TagLostException) {
setInstruction(getString(R.string.instruction_tag_lost))
setState(CredentialBottomSheet.State.TAG_LOST)
} else {
setInstruction(getString(R.string.error_format, e.toUserMessage(this)))
setState(CredentialBottomSheet.State.ERROR)
}
}
}

View File

@@ -7,4 +7,7 @@
<!-- Provider status - not enabled (dark theme) -->
<color name="provider_not_enabled_background">#BF360C</color>
<color name="provider_not_enabled_text">#FFCC80</color>
<!-- Tag lost warning state -->
<color name="warning_container">#7C2D12</color>
</resources>

View File

@@ -7,4 +7,7 @@
<!-- Provider status - not enabled (light theme) -->
<color name="provider_not_enabled_background">#FFF3E0</color>
<color name="provider_not_enabled_text">#E65100</color>
<!-- Tag lost warning state -->
<color name="warning_container">#FED7AA</color>
</resources>

View File

@@ -27,6 +27,7 @@
<string name="instruction_initializing">Initializing…</string>
<string name="instruction_verifying">Verifying…</string>
<string name="instruction_verifying_pin">Verifying PIN…</string>
<string name="instruction_tag_lost">Lost contact with the security key\n\nReposition and hold until completion</string>
<!-- PIN Dialog -->
<string name="pin_dialog_title">Security Key PIN</string>