parkbsu

OAuth for Android - webview, ICS and protocol not supported

1 post in this topic

I have been experimenting with the HelloEDAM sample project for Android and how the OAuth implementation is handled, and while I thought I had things working on a Android 2.3.6 device, that same code fails on ICS (4.0.4).

I checked stackoverflow and a few other web sites to see if I could find an explanation for the ICS error I'm receiving, but I didn't have any luck. Maybe someone in this forum would have an idea?

So here's what I did..

Using the original source for com.evernote.client.oauth.android.EvernoteOAuthActivity, I modified the activity to use a webview instead of an intent for the OAuth authentication. Reason being, aesthetically, I would rather have a webview wrapped within the overall look and feel of my app rather than sending the user out to a new browser window to handle OAuth login.

Here's a bit of the code that I changed:


private void beginAuthentication() {
try {
OAuthService service = createService();
Log.i(TAG, "Retrieving OAuth request token...");
Token requestToken = service.getRequestToken();
this.requestToken = requestToken.getToken();
this.requestTokenSecret = requestToken.getSecret();

// Open a browser to allow the user to authorize access to their account
Log.i(TAG, "Redirecting user for authorization...");
String url = service.getAuthorizationUrl(requestToken);


// TODO set this to be centered in the screen, not full-screen
final WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
webview.setVerticalScrollBarEnabled(false);
webview.setHorizontalScrollBarEnabled(false);
webview.setVisibility(View.VISIBLE);
setContentView(webview);
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();

//WebViewClient must be set BEFORE calling loadUrl!
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
if (url.startsWith(getCallbackScheme()) && url != null) {
//webview.setVisibility(View.GONE);
System.out.println("onPageFinished : " + url);
authToken = completeAuth(Uri.parse(url));
receivedCallback = true;
// Commented out to see the error message
//finish();
}
}
// Used for debugging
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Log.e(TAG, "Error: " + description);
Toast.makeText(EvernoteOAuthActivity.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
alertDialog.setTitle("Error");
alertDialog.setMessage(description + " " + errorCode);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
});

webview.loadUrl(url);

//Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
//startActivity(intent);
} catch (OAuthException oax) {
// TODO communicate this back to the caller
Log.e(TAG, "Failed to obtain OAuth request token", oax);
finish();
} catch (Exception ex) {
Log.e(TAG, "Failed to obtain OAuth request token", ex);
finish();
}
}

Without going into too much of the other code, suffice it to say, I *think* I added/removed all of the necessary bits to get things working (i.e., I commented out the onNewIntent method and moved some other code around).

This approach works fine on a 2.3.6 device. The Evernote login page appears - I enter my username and password. The "Authorize" and "Decline" page appears and on 2.3.6 when it completes, I get my token in the form of "en-xxx://callback?oauth_token=xxx.1234".

However, when I try it on ICS, I run into problems. The Evernote login page still appears, I am still able to enter my username and password. I can still select "Authorize" or "Decline" but when that completes, instead of getting the token, I get an error message (as provided by onReceivedError) that states "protocol not supported" with an error code of -10. And instead of a webpage that displays the token, it reads "webpage not available".

I also receive the following errors in Eclipse:


05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): Failed to obtain OAuth access token
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): org.scribe.exceptions.OAuthException: Problems while creating connection.
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.model.Request.send(Request.java:70)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.model.OAuthRequest.send(OAuthRequest.java:12)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.oauth.OAuth10aServiceImpl.getAccessToken(OAuth10aServiceImpl.java:81)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at com.evernote.client.oauth.android.EvernoteOAuthActivity.completeAuth(EvernoteOAuthActivity.java:264)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at com.evernote.client.oauth.android.EvernoteOAuthActivity.access$1(EvernoteOAuthActivity.java:250)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at com.evernote.client.oauth.android.EvernoteOAuthActivity$1.onPageFinished(EvernoteOAuthActivity.java:208)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:275)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at android.os.Handler.dispatchMessage(Handler.java:99)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at android.os.Looper.loop(Looper.java:137)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at java.lang.reflect.Method.invokeNative(Native Method)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at java.lang.reflect.Method.invoke(Method.java:511)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at dalvik.system.NativeStart.main(Native Method)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): Caused by: java.io.IOException: Received authentication challenge is null
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:133)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.model.Response.<init>(Response.java:28)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.model.Request.doSend(Request.java:110)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): at org.scribe.model.Request.send(Request.java:62)
05-03 08:56:53.723: E/EvernoteOAuthActivity(13030): ... 14 more

The thing is, immediately before that I do have a token - the OAuth process works, the webview just doesn't know how to handle the response (this is coming from onPageFinished in the webview client):


05-03 08:56:53.293: I/System.out(13030): onPageFinished : en-xxx://callback?oauth_token=xxx.1234.4567&oauth_verifier=357
05-03 08:56:53.293: I/EvernoteOAuthActivity(13030): Retrieving OAuth access token...

So, my questions are:

1. Is it possible to do OAuth on Android using a Webview instead of opening a browser window, temporarily leaving the app?

2. If so, is there a way around this error on ICS?

Thanks for the help!

Share this post


Link to post