Il framework dell'adattatore di sincronizzazione presuppone che trasferisca i dati tra lo spazio di archiviazione del dispositivo associato a un account e lo spazio di archiviazione del server che richiede l'accesso. Per questo motivo, il framework si aspetta che tu fornisca un componente chiamato autenticatore all'interno dell'adattatore di sincronizzazione. Questo componente si collega agli account e al framework di autenticazione Android e fornisce un'interfaccia standard per la gestione delle credenziali utente, ad esempio le informazioni di accesso.
Anche se la tua app non usa account, devi comunque fornire un componente di autenticazione.
Se non utilizzi account o accesso al server, le informazioni gestite dall'autenticatore vengono ignorate, quindi puoi fornire un componente di autenticazione che contiene le implementazioni del metodo stub. Devi inoltre fornire un Service
associato che consenta al framework dell'adattatore di sincronizzazione di chiamare i metodi dell'autenticatore.
Questa lezione spiega come definire tutte le parti di un autenticatore stub necessarie per soddisfare i requisiti del framework dell'adattatore di sincronizzazione. Se devi fornire un autenticatore reale che gestisca gli account utente, leggi la documentazione di riferimento per AbstractAccountAuthenticator
.
Aggiungi un componente di autenticazione stub
Per aggiungere un componente di autenticazione stub alla tua app, crea una classe che estenda AbstractAccountAuthenticator
, quindi analizza i metodi richiesti, restituendo null
o generando un'eccezione.
Lo snippet seguente mostra un esempio di classe di autenticazione stub:
Kotlin
/* * Implement AbstractAccountAuthenticator and stub out all * of its methods */ class Authenticator(context: Context) // Simple constructor : AbstractAccountAuthenticator(context) { // Editing properties is not supported override fun editProperties(r: AccountAuthenticatorResponse, s: String): Bundle { throw UnsupportedOperationException() } // Don't add additional accounts @Throws(NetworkErrorException::class) override fun addAccount( r: AccountAuthenticatorResponse, s: String, s2: String, strings: Array<String>, bundle: Bundle ): Bundle? = null // Ignore attempts to confirm credentials @Throws(NetworkErrorException::class) override fun confirmCredentials( r: AccountAuthenticatorResponse, account: Account, bundle: Bundle ): Bundle? = null // Getting an authentication token is not supported @Throws(NetworkErrorException::class) override fun getAuthToken( r: AccountAuthenticatorResponse, account: Account, s: String, bundle: Bundle ): Bundle { throw UnsupportedOperationException() } // Getting a label for the auth token is not supported override fun getAuthTokenLabel(s: String): String { throw UnsupportedOperationException() } // Updating user credentials is not supported @Throws(NetworkErrorException::class) override fun updateCredentials( r: AccountAuthenticatorResponse, account: Account, s: String, bundle: Bundle ): Bundle { throw UnsupportedOperationException() } // Checking features for the account is not supported @Throws(NetworkErrorException::class) override fun hasFeatures( r: AccountAuthenticatorResponse, account: Account, strings: Array<String> ): Bundle { throw UnsupportedOperationException() } }
Java
/* * Implement AbstractAccountAuthenticator and stub out all * of its methods */ public class Authenticator extends AbstractAccountAuthenticator { // Simple constructor public Authenticator(Context context) { super(context); } // Editing properties is not supported @Override public Bundle editProperties( AccountAuthenticatorResponse r, String s) { throw new UnsupportedOperationException(); } // Don't add additional accounts @Override public Bundle addAccount( AccountAuthenticatorResponse r, String s, String s2, String[] strings, Bundle bundle) throws NetworkErrorException { return null; } // Ignore attempts to confirm credentials @Override public Bundle confirmCredentials( AccountAuthenticatorResponse r, Account account, Bundle bundle) throws NetworkErrorException { return null; } // Getting an authentication token is not supported @Override public Bundle getAuthToken( AccountAuthenticatorResponse r, Account account, String s, Bundle bundle) throws NetworkErrorException { throw new UnsupportedOperationException(); } // Getting a label for the auth token is not supported @Override public String getAuthTokenLabel(String s) { throw new UnsupportedOperationException(); } // Updating user credentials is not supported @Override public Bundle updateCredentials( AccountAuthenticatorResponse r, Account account, String s, Bundle bundle) throws NetworkErrorException { throw new UnsupportedOperationException(); } // Checking features for the account is not supported @Override public Bundle hasFeatures( AccountAuthenticatorResponse r, Account account, String[] strings) throws NetworkErrorException { throw new UnsupportedOperationException(); } }
Associa l'autenticatore al framework
Affinché il framework dell'adattatore di sincronizzazione possa accedere all'autenticatore, devi creare un servizio associato. Questo servizio fornisce un oggetto binder Android che consente al framework di chiamare l'autenticatore e trasferire dati tra quest'ultimo e il framework.
Lo snippet seguente mostra come definire il limite Service
:
Kotlin
/** * A bound Service that instantiates the authenticator * when started. */ class AuthenticatorService : Service() { // Instance field that stores the authenticator object private lateinit var mAuthenticator: Authenticator override fun onCreate() { // Create a new authenticator object mAuthenticator = Authenticator(getApplicationContext()) } /* * When the system binds to this Service to make the RPC call * return the authenticator's IBinder. */ override fun onBind(intent: Intent?): IBinder = mAuthenticator.iBinder }
Java
/** * A bound Service that instantiates the authenticator * when started. */ public class AuthenticatorService extends Service { ... // Instance field that stores the authenticator object private Authenticator mAuthenticator; @Override public void onCreate() { // Create a new authenticator object mAuthenticator = new Authenticator(getApplicationContext()); } /* * When the system binds to this Service to make the RPC call * return the authenticator's IBinder. */ @Override public IBinder onBind(Intent intent) { return mAuthenticator.getIBinder(); } }
Aggiungi il file di metadati dell'autenticatore
Per collegare il componente di autenticazione all'adattatore di sincronizzazione e ai framework dell'account, devi fornire a questo framework i metadati che descrivono il componente. Questi metadati dichiarano il
tipo di account che hai creato per l'adattatore di sincronizzazione e gli elementi dell'interfaccia utente
visualizzati dal sistema se vuoi rendere visibile il tipo di account all'utente. Dichiara questi metadati in un file XML archiviato nella directory /res/xml/
del progetto dell'app.
Puoi assegnare qualsiasi nome al file, anche se di solito si chiama authenticator.xml
.
Questo file XML contiene un singolo elemento <account-authenticator>
con i seguenti attributi:
-
android:accountType
-
Il framework dell'adattatore di sincronizzazione richiede che ogni adattatore di sincronizzazione abbia un tipo di account, sotto forma di nome di dominio. Il framework utilizza il tipo di account nell'identificazione interna dell'adattatore di sincronizzazione. Per i server che richiedono l'accesso, il tipo di account e un
account utente vengono inviati al server come parte delle credenziali di accesso.
Se il server non richiede l'accesso, devi comunque fornire un tipo di account. Per il valore, utilizza un nome di dominio controllato da te. Sebbene il framework lo utilizzi per gestire l'adattatore di sincronizzazione, il valore non viene inviato al server.
-
android:icon
-
Puntatore a una risorsa Drawable contenente un'icona. Se rendi visibile l'adattatore di sincronizzazione specificando l'attributo
android:userVisible="true"
inres/xml/syncadapter.xml
, devi fornire questa risorsa icona. e riportato nella sezione Account dell'app Impostazioni del sistema. -
android:smallIcon
-
Punta a una risorsa Drawable contenente una versione ridotta dell'icona. Questa risorsa potrebbe essere utilizzata al posto di
android:icon
nella sezione Account dell'app Impostazioni del sistema, a seconda delle dimensioni dello schermo. -
android:label
-
Stringa localizzabile che identifica il tipo di account per gli utenti. Se rendi visibile l'adattatore di sincronizzazione specificando l'attributo
android:userVisible="true"
inres/xml/syncadapter.xml
, devi fornire questa stringa. Viene visualizzata nella sezione Account dell'app Impostazioni del sistema, accanto all'icona che definisci per l'autenticatore.
Lo snippet seguente mostra il file XML dell'autenticatore che hai creato in precedenza:
<?xml version="1.0" encoding="utf-8"?> <account-authenticator xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="example.com" android:icon="@drawable/ic_launcher" android:smallIcon="@drawable/ic_launcher" android:label="@string/app_name"/>
Dichiara l'autenticatore nel file manifest
In un passaggio precedente, hai creato un Service
associato che collega l'autenticatore al framework dell'adattatore di sincronizzazione. Per identificare questo servizio nel sistema, dichiaralo nel file manifest dell'app aggiungendo il seguente elemento <service>
come elemento secondario di <application>
:
<service android:name="com.example.android.syncadapter.AuthenticatorService"> <intent-filter> <action android:name="android.accounts.AccountAuthenticator"/> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator" /> </service>
L'elemento
<intent-filter>
configura un filtro che viene attivato dall'azione intent
android.accounts.AccountAuthenticator
, che viene inviato dal sistema per eseguire l'autenticatore. Quando viene attivato il filtro, il sistema avvia AuthenticatorService
,
il vincolo Service
che hai fornito per eseguire il wrapping dell'autenticatore.
L'elemento
<meta-data>
dichiara i metadati per l'autenticatore. L'attributo android:name
collega i metadati al framework di autenticazione. L'elemento
android:resource
specifica il nome del file di metadati dell'autenticatore che hai creato in precedenza.
Oltre a un autenticatore, un adattatore di sincronizzazione richiede anche un fornitore di contenuti. Se la tua app non utilizza già un fornitore di contenuti, vai alla lezione successiva per scoprire come creare un provider di contenuti stub; altrimenti, vai alla lezione Creazione di un adattatore di sincronizzazione.