Reputation: 730
When my App launches the MainActivity comes to us, there are not any tokens at this moment so it fails to find token in AccountManager so it goes into LoginActivity.
We input account and password the get token from remote server and save it in local AccountManager。then return to MainActivity.
When come back MainActivity again. I fail to get the local token even it actually exists now. So the app will go into LoginActivity again. If I exit the app and launch it again at this moment, the Mainactivity is able to get the existing token now.
I add token into header in Interceptor of Retrofit 2.0 in this way:
private volatile static Retrofit jsonInstance;
// Returns singleton class instance
public static Retrofit getJsonInstance(final Context context) {
if (jsonInstance == null) {
synchronized (Retrofit.class) {
if (jsonInstance == null) {
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
GitHubAccount gitHubAccount = GitHubAccount.getInstance(context);
//Get token here
token = gitHubAccount.getAuthToken();
request = request.newBuilder()
.removeHeader("User-Agent")
.addHeader("Authorization", "Token " + token)
.addHeader("User-Agent", "Leaking/1.0")
//.addHeader("Accept", "application/vnd.github.beta+json")
.addHeader("Accept", "application/vnd.github.v3.raw")
.build();
return chain.proceed(request);
}
});
Gson gson = new Gson();
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Event.class, new EventFormatter());
gson = builder.create();
jsonInstance = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
}
}
}
return jsonInstance;
}
the getAuthToken() method
public String getAuthToken() {
final AccountManagerFuture<Bundle> future = manager.getAuthToken(account, ACCOUNT_TYPE, null, (BaseActivity)context, null, null);
try {
Bundle result = future.getResult();
return result.getString(AccountManager.KEY_AUTHTOKEN);
} catch (AccountsException e) {
Log.e(TAG, "Auth token lookup failed", e);
return null;
} catch (IOException e) {
Log.e(TAG, "Auth token lookup failed", e);
return null;
}
}
and then the procedure of manager.getAuthToken
will happens in the my custom AccountAuthenticator
@Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
final AccountManager am = AccountManager.get(context);
String authToken = am.peekAuthToken(account, authTokenType);
if (TextUtils.isEmpty(authToken)) {
final String password = am.getPassword(account);
if (password != null) {
Github github = new GithubImpl(context);
try {
//Get token from server
authToken = github.createToken(account.name,password);
} catch (GithubError githubError) {
githubError.printStackTrace();
authToken = "";
} catch (AuthError authError) {
authError.printStackTrace();
authToken = "";
} catch (OverAuthError overAuthError) {
overAuthError.printStackTrace();
authToken = "";
}
}else {
Log.i(TAG, "Try to get AuthToken password is empty");
}
}
if (!TextUtils.isEmpty(authToken)) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
return result;
}
// If we get here, then we couldn't access the user's password - so we
// need to re-prompt them for their credentials. We do that by creating
// an intent to display our AuthenticatorActivity.
final Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(ARG_AUTH_TYPE, authTokenType);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}
The total project is here https://github.com/Leaking/WeGit
Upvotes: 0
Views: 803
Reputation: 21
Maybe the problem is that you are saving the token in a async process and the saving method is slower than the Get method.
Upvotes: 0