Quando la mia app visualizza "Troppi tentativi ...", errore di autenticazione 0x7, FINGERPRINT_ERROR_LOCKOUT, come posso dire senza chiamare FingerprintManager.authenticate() in un ciclo e ricevendo l'errore che la condizione di blocco è stata cancellata?Come dire programmaticamente quando FINGERPRINT_ERROR_LOCKOUT è scaduto su Android FIngerprintManager?
risposta
Guardando all'implementazione AOSP del sistema FingerprintService, esiste effettivamente un tentativo di trasmissione che viene inviato dopo la scadenza del periodo di blocco. L'azione intentata per cercare è com.android.server.fingerprint.ACTION_LOCKOUT_RESET
.
nella vostra attività, è possibile registrare un ricevitore broadcast e attendere questo intento, in questo modo:
public class MyActivity extends Activity {
...
private static final String ACTION_LOCKOUT_RESET =
"com.android.server.fingerprint.ACTION_LOCKOUT_RESET";
private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_LOCKOUT_RESET.equals(intent.getAction())) {
doWhateverYouNeedToDoAfterLockoutHasBeenReset();
}
}
};
private void registerLockoutResetReceiver() {
Intent ret = getContext().registerReceiver(mLockoutReceiver, new IntentFilter(ACTION_LOCKOUT_RESET),
null, null);
}
public void onCreate(Bundle savedInstanceState) {
registerLockoutResetReceiver();
...
}
...
}
ATTENZIONE: questo non fa parte delle API pubblica e così, questo comportamento può cambiare con qualsiasi aggiornamento del sistema operativo successivo. Ma l'ho provato su Nougat e funziona abbastanza bene per me.
Riferimento:
Il codice AOSP rilevante è ./frameworks/base/services/core/java/com/android/server/fingerprint/FingerprintService.java. In questo file, possiamo trovare un PendingIntent
con una ACTION_LOCKOUT_RESET
intento in fase di creazione:
private PendingIntent getLockoutResetIntent() {
return PendingIntent.getBroadcast(mContext, 0,
new Intent(ACTION_LOCKOUT_RESET), PendingIntent.FLAG_UPDATE_CURRENT);
}
Questa PendingIntent è iscritto ad essere compensati dopo qualche tempo trascorso dalla AlarmManager:
private void scheduleLockoutReset() {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + FAIL_LOCKOUT_TIMEOUT_MS, getLockoutResetIntent());
}
Ho provato questo, ma dopo aver ricevuto la trasmissione, il dispositivo di impronte digitali non reagirebbe a nessuna scansione delle impronte digitali. Ho dovuto riavviare l'attività per eseguire nuovamente la scansione. Qualcuno ha visto un problema simile? –
@JeffreyLiu Dopo il blocco, è necessario riavviare il gestore del dispositivo di impronte digitali. – hopia
Come si riavvia? @hopia –
Tra le tante cose che ho provato stava chiamando 'hasEnrolledFingerprints()' e 'isHardwareDetected()' durante il periodo di blocco per vedere se sarebbe ritornato o lanciato qualche sorta di eccezione. Non c'è fortuna, quelle chiamate funzionano come previsto. – neuman8
Hai trovato una soluzione per questo? Vorrei anche sapere il tempo di blocco rimanente e se il dispositivo è bloccato prima di chiamare authenticate(). – Niels
@Niels Non l'ho più seguito, ma una rapida occhiata all'ultima versione del codice sorgente di FingerprintManager.java mi mostra qualcosa del tipo: 'public static abstract class LockoutResetCallback { // Chiamato quando il periodo di blocco è scaduto e i client sono consentiti per ascoltare di nuovo le impronte digitali. public void onLockoutReset() {} } ' – neuman8