@@ -237,6 +237,9 @@ class MainActivity : AppCompatActivity() {
237237 private var installUris: ArrayList <Uri >? = null
238238 private lateinit var permissionHandler: PermissionRequestHandler
239239 private val isLocked = mutableStateOf(false )
240+ private var isAuthenticated = false
241+ private var biometricPromptShowing = false
242+ private var startupSoundPlayed = false
240243 private var pendingActionModuleId by mutableStateOf<String ?>(null )
241244 private var pendingScriptId by mutableStateOf<String ?>(null )
242245
@@ -368,6 +371,17 @@ class MainActivity : AppCompatActivity() {
368371 // 初始化权限处理器
369372 permissionHandler = PermissionRequestHandler (this )
370373
374+ setupUI()
375+ }
376+
377+ override fun onResume () {
378+ super .onResume()
379+ showBiometricPromptIfNeeded()
380+ }
381+
382+ private fun showBiometricPromptIfNeeded () {
383+ if (isAuthenticated || biometricPromptShowing) return
384+
371385 val prefs = APApplication .sharedPreferences
372386 val biometricLogin = prefs.getBoolean(" biometric_login" , false )
373387 val biometricManager = androidx.biometric.BiometricManager .from(this )
@@ -379,21 +393,34 @@ class MainActivity : AppCompatActivity() {
379393 val isShareIntent = intent.action == Intent .ACTION_SEND || intent.action == Intent .ACTION_SEND_MULTIPLE
380394 if (biometricLogin && canAuthenticate && ! isShareIntent) {
381395 isLocked.value = true
396+ biometricPromptShowing = true
382397 val biometricPrompt = androidx.biometric.BiometricPrompt (
383398 this ,
384399 androidx.core.content.ContextCompat .getMainExecutor(this ),
385400 object : androidx.biometric.BiometricPrompt .AuthenticationCallback () {
386401 override fun onAuthenticationError (errorCode : Int , errString : CharSequence ) {
387402 super .onAuthenticationError(errorCode, errString)
388- showToast(this @MainActivity, errString.toString())
389- finishAndRemoveTask()
403+ biometricPromptShowing = false
404+ if (errorCode == androidx.biometric.BiometricPrompt .ERROR_USER_CANCELED ) {
405+ finishAndRemoveTask()
406+ } else {
407+ Handler (Looper .getMainLooper()).postDelayed({
408+ if (! isAuthenticated && ! biometricPromptShowing) {
409+ showBiometricPromptIfNeeded()
410+ }
411+ }, 300 )
412+ }
390413 }
391414
392415 override fun onAuthenticationSucceeded (result : androidx.biometric.BiometricPrompt .AuthenticationResult ) {
393416 super .onAuthenticationSucceeded(result)
394417 isLocked.value = false
395- // Play startup sound after biometric auth success
396- me.bmax.apatch.util.SoundEffectManager .playStartup(this @MainActivity)
418+ isAuthenticated = true
419+ biometricPromptShowing = false
420+ if (! startupSoundPlayed) {
421+ startupSoundPlayed = true
422+ me.bmax.apatch.util.SoundEffectManager .playStartup(this @MainActivity)
423+ }
397424 }
398425 })
399426 val promptInfo = androidx.biometric.BiometricPrompt .PromptInfo .Builder ()
@@ -402,11 +429,14 @@ class MainActivity : AppCompatActivity() {
402429 .setAllowedAuthenticators(androidx.biometric.BiometricManager .Authenticators .BIOMETRIC_STRONG or androidx.biometric.BiometricManager .Authenticators .DEVICE_CREDENTIAL )
403430 .build()
404431 biometricPrompt.authenticate(promptInfo)
405- } else {
406- // Play startup sound directly if no biometric auth needed
407- me.bmax.apatch.util.SoundEffectManager .playStartup(this )
432+ } else if (! biometricLogin || ! canAuthenticate || isShareIntent) {
433+ isAuthenticated = true
434+ isLocked.value = false
435+ if (! startupSoundPlayed) {
436+ startupSoundPlayed = true
437+ me.bmax.apatch.util.SoundEffectManager .playStartup(this )
438+ }
408439 }
409- setupUI()
410440 }
411441
412442 private fun setupUI () {
0 commit comments