I'm trying to use OAuth in an Android app. I have it working correctly but have sometimes run into a problem during the authentication phase. In Android, I launch the browser for the user to login and authenticate. Then the callback url will redirect back to my application.
Here is the problem. My application has a OAuth consumer and provider as members of my main class. When the browser is launched for authentication, sometimes my main Activity is discarded to save memory. When the callback url relaunches my main Activity, the provider and consumer are new instances and therefor don't work when I try to make a request to the api. If the main Activiy was not freed during the authentication phase, then everything works correctly because I'm still working with the original consumer and provider.
I tried using onSaveInstanceState() and onRestoreInstanceState(), but haven't been successful. It seems the onRestoreInstanceState() is not called when my callback url is handled. Seems to go straight to the onResume().
What is the correct method for persisting the consumer and provider in this case?
Complete Save / restore solution
Apart from the request_token
and token_secret
, the isOauth10a()
state is important to be restored in the provider. There could be more state information in the future. Hence, I like the persist and load solution the best.
I extended GrkEngineer's solution to be more complete. It saves / restores both the provider and consumer, handles all exceptions, and sets the httpClient while restoring.
protected void loadProviderConsumer()
{
try {
FileInputStream fin = this.openFileInput("tmp_provider.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
provider = (CommonsHttpOAuthProvider) ois.readObject();
provider.setHttpClient(httpClient);
ois.close();
fin.close();
fin = this.openFileInput("tmp_consumer.dat");
ois = new ObjectInputStream(fin);
consumer = (CommonsHttpOAuthConsumer) ois.readObject();
ois.close();
fin.close();
Log.d("OAuthTwitter", "Loaded state");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
protected void persistProviderConsumer()
{
try {
FileOutputStream fout = this.openFileOutput("tmp_provider.dat", MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(provider);
oos.close();
fout.close();
fout = this.openFileOutput("tmp_consumer.dat", MODE_PRIVATE);
oos = new ObjectOutputStream(fout);
oos.writeObject(consumer);
oos.close();
fout.close();
Log.d("OAuthTwitter", "Saved state");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have tested this code and it works.
You can read my old post here. Generally what I've done was to use static reference and using Activity with WebView instead of standalone browser to display authentication form
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With