I’ve just had a dig through the Twitter code and come up with a workaround, it’s not 100% as clean as I would like but I didn’t want to use reflection to clear the authentication in progress (which is what TwitterLoginButton does).
The problem is TwitterCore.getInstance().logIn() creates an instance of TwitterAuthClient that we don’t get access to in order to grab a reference its internal AuthState which provides the method to endAuthorize() and allow the user to try again. TwitterLoginButton does provide a mechanism to do this by handling our onActivityResult() response.
The good news is the default constructor for TwitterAuthClient uses a whole load of singletons/static instances, so all we need to do is construct our own to mimic this behaviour. e.g.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// handle cancelled Twitter login (resets TwitterCore.*AuthHandler.AuthState)
final TwitterAuthClient twitterAuthClient = new TwitterAuthClient();
if(twitterAuthClient.getRequestCode()==requestCode) {
twitterLoginWasCanceled = (resultCode == RESULT_CANCELED);
twitterAuthClient.onActivityResult(requestCode, resultCode, data);
}
}
Note that AuthHandler which ends up acting on the resultCode treats RESULT_CANCELLED as an error which ends up triggering the TwitterCore.getInstance().login()'s Callback.failure() passing a TwitterAuthException (a bug?). This is why I catch the RESULT_CANCELLED above, so that I know to ignore the error when it happens.