Zaloguj się dwa razy podczas korzystania z SyncAdapters
Tworzę nową aplikację na Androida za pomocą SyncAdapter
do obsługi db sync.
Mam wszystko na miejscu i aplikacja działa dobrze, ale zauważyłem, że jestem zalogowany dwa razy.
Pierwsze logowanie odbywa się, gdy klasa AuthenticatorActivity
(rozszerza AccountAuthenticatorActivity
) waliduje użytkownika i hasło.
Jeśli użytkownik i hasło są poprawne {[2] } to robi:
- Jeśli
account
nie istnieje, tworzy go za pomocąmAccountManager.addAccountExplicitly()
-
authToken
jest zapisywany za pomocąintent.putExtra(AccountManager.KEY_AUTHTOKEN, authToken);
To było zasadniczo skopiowane / wklejone z próbek Androida, więc myślę, że jest ok.
Problem polega na tym, że gdy SyncAdapter
uruchamia i używa
authtoken = mAccountManager.blockingGetAuthToken(account,
AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, true);
Wywoływana jest metoda getAuthToken()
wewnątrz klasy Authenticator
, która rozszerza AbstractAccountAuthenticator
. I wewnątrz tej metody ponownie uderzam w punkt końcowy logowania.
Od tego momentu punkt końcowy logowania nie zostanie ponownie trafiony, dopóki authToken
nie wygaśnie.
To nie jest coś, co przeszkadza mi bardzo, ale chciałbym wiedzieć, czy jest sposób, aby unikaj logowania dwa razy.
1 answers
Jak już widzieliście, choć Authenticator.java
w SampleSyncAdapter mówi
To kłamstwo.Interesującą rzeczą, którą demonstruje ta klasa, jest użycie authTokens jako części procesu uwierzytelniania. ... Jeśli mamy już authtoken zapisane na koncie, zwracamy ten authToken. Jeśli nie, ale mamy nazwę użytkownika i hasło, spróbujemy porozmawiać z usługą przykładową, aby pobrać authToken.
Authenticator.getAuthToken
nie sprawdza pamięci podręcznej, tylko uderza w sieć, aby uzyskać token.
Rozwiązaniem jest dodanie w brakującym czeku:
Authenticator.java:
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
String authTokenType, Bundle loginOptions) throws NetworkErrorException {
// check that authToken type supported
...
// Check if we already have a cached token to return
final AccountManager am = AccountManager.get(mContext);
String cachedAuthToken = am.peekAuthToken(account, authTokenType);
if (cachedAuthToken != null) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, cachedAuthToken);
return result;
}
// Get new authToken from server
...
// If all else fails, prompt the user for credentials
...
}
Zauważ, że reszta twojego projektu musi być religijnie używana AccountManager.invalidateAuthToken
, gdy wywołania się nie powiodą, w przeciwnym razie skończysz z nieskończoną pętlą wywołań, próbując uzyskać nowy token auth, a następnie zawiedziesz ponownie, gdy ten sam buforowany Token auth zostanie zwrócony.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-30 20:24:07