Crea un tipo di account personalizzato

Finora abbiamo parlato dell'accesso alle API di Google, che utilizzano account e utenti definiti da Google. Se invece hai un servizio online, non avrà Account Google o utenti, quindi che cosa fai? Risulta relativamente semplice installare nuovi tipi di account sul dispositivo di un utente. Questa lezione spiega come creare un tipo di account personalizzato che funziona come gli account integrati.

Implementa il codice personalizzato dell'account

La prima cosa di cui hai bisogno è un modo per ottenere le credenziali dall'utente. Può trattarsi, ad esempio, di una finestra di dialogo che richiede un nome e una password. Oppure potrebbe essere una procedura più esotica, come una password monouso o una scansione biometrica. In ogni caso, è tua responsabilità implementare il codice che:

  1. Raccoglie le credenziali dell'utente
  2. Autentica le credenziali con il server
  3. Archivia le credenziali sul dispositivo

Generalmente tutti e tre questi requisiti possono essere gestiti da un'unica attività. che chiameremo attività di autenticazione.

Poiché devono interagire con il sistema AccountManager, le attività di autenticazione hanno determinati requisiti che non sono previsti per le attività normali. Per semplificare la procedura, il framework Android fornisce una classe di base, AccountAuthenticatorActivity, che puoi estendere per creare il tuo autenticatore personalizzato.

La modalità di gestione dei primi due requisiti dell'attività di autenticazione, la raccolta delle credenziali e l'autenticazione, dipende completamente da te. Se ci fosse un solo modo per farlo, dopotutto non ci sarebbe bisogno di tipi di account "personalizzati". Il terzo requisito prevede un'implementazione canonica e piuttosto semplice:

Kotlin

Account(username, your_account_type).also { account ->
    accountManager.addAccountExplicitly(account, password, null)
}

Java

final Account account = new Account(username, your_account_type);
accountManager.addAccountExplicitly(account, password, null);

Fai attenzione alla sicurezza!

È importante capire che AccountManager non è un servizio di crittografia o un portachiavi. Archivia le credenziali dell'account così come le trasmetti, in testo normale. Sulla maggior parte dei dispositivi, questo non è un problema particolare, perché li archivia in un database accessibile solo al root. Tuttavia, su un dispositivo rooted, le credenziali sono leggibili da chiunque abbia accesso al dispositivo con adb.

Tenendo conto di ciò, non devi trasmettere la password effettiva dell'utente a AccountManager.addAccountExplicitly(). Dovresti invece archiviare un token crittografico sicuro che sarebbe di uso limitato per un utente malintenzionato. Se le tue credenziali utente proteggono qualcosa di importante, dovresti valutare con attenzione di fare qualcosa di simile.

Ricorda: per quanto riguarda il codice di sicurezza, segui la regola dei "Miti": non provarlo a casa! Consulta un professionista della sicurezza prima di implementare un codice account personalizzato.

Ora che non trovi più i disclaimer sulla sicurezza, puoi riprendere il lavoro. Hai già implementato la parte essenziale del tuo codice account personalizzato; ciò che rimane sono idraulici.

Estendi AbstractAccountAuthenticator

Affinché AccountManager funzioni con il tuo codice account personalizzato, è necessaria una classe che implementi le interfacce previste da AccountManager. che corrisponde alla classe di Authenticator.

Il modo più semplice per creare una classe di Authenticator è estendere AbstractAccountAuthenticator e implementare i relativi metodi astratti. Se hai seguito le lezioni precedenti, i metodi astratti di AbstractAccountAuthenticator dovrebbero sembrare familiari: sono l'opposto dei metodi che hai chiamato nella lezione precedente per ottenere informazioni sull'account e token di autorizzazione.

L'implementazione corretta di una classe di autenticazione richiede una serie di frammenti di codice separati. Innanzitutto, AbstractAccountAuthenticator ha sette metodi astratti che devi sostituire. Inoltre, devi aggiungere un filtro intent per "android.accounts.AccountAuthenticator" al manifest dell'applicazione (mostrato nella sezione successiva). Infine, devi fornire due risorse XML che definiscano, tra le altre cose, il nome del tipo di account personalizzato e l'icona che verrà visualizzata dal sistema accanto agli account di questo tipo.

Puoi trovare una guida passo passo per implementare una classe di autenticazione riuscita e i file XML nella documentazione di AbstractAccountAuthenticator.

Se l'attività di autenticazione richiede parametri di inizializzazione speciali, puoi collegarli all'intent utilizzando Intent.putExtra().

Crea un servizio di autenticazione

Ora che hai una classe di Authenticator, ti serve un posto dove farlo. Gli autenticatori dell'account devono essere disponibili per più applicazioni e lavorare in background, quindi devono essere eseguiti all'interno di un Service. Chiameremo questo servizio di autenticazione.

Il tuo servizio di autenticazione può essere molto semplice. Non deve fare altro che creare un'istanza della classe di autenticazione in onCreate() e chiamare getIBinder() in onBind().

Non dimenticare di aggiungere un tag <service> al file manifest, aggiungi un filtro di intent per l'intent AccountAuthenticator e dichiari l'autenticatore dell'account:

<service ...>
   <intent-filter>
      <action android:name="android.accounts.AccountAuthenticator" />
   </intent-filter>
   <meta-data android:name="android.accounts.AccountAuthenticator"
             android:resource="@xml/authenticator" />
</service>

Distribuisci il servizio

A questo punto, la procedura è completata. Il sistema ora riconosce il tipo di account, insieme a tutti i tipi di account noti, come "Google" e "Azienda". Puoi utilizzare la pagina Impostazioni account e sincronizzazione per aggiungere un account. Le app che richiedono account di tipo personalizzato potranno enumerare e autenticarsi come farebbero con qualsiasi altro tipo di account.

Tutto questo presuppone che il servizio dell'account sia effettivamente installato sul dispositivo. Se solo un'app accede al servizio, non è un problema: devi solo associarlo nell'app. Se invece vuoi che il servizio del tuo account venga utilizzato da più di un'app, la situazione si fa più complicata. Non vuoi raggruppare il servizio con tutte le tue app e averne più copie che occupano spazio sul dispositivo dell'utente.

Una soluzione è inserire il servizio in un piccolo APK per scopi speciali. Quando un'app vuole utilizzare il tuo tipo di account personalizzato, può controllare il dispositivo per vedere se il servizio del tuo account personalizzato è disponibile. In caso contrario, può indirizzare l'utente a Google Play per scaricare il servizio. All'inizio potrebbe sembrare un grosso problema, ma, rispetto all'alternativa del reinserimento delle credenziali per ogni app che utilizza il tuo account personalizzato, è facilissimo.