• Announcements

    • Shane D.

      Evernote Webinars   12/01/2017

      We've recently begun conducting Evernote Webinars for various topics and subjects. Take a look at the Calendar to check them out, and see if they interest you! Keep an eye out as there will be more to come in the future!
parkbsu

OAuth for Android - webview, ICS and protocol not supported

Recommended Posts

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