I'm working on an android application for my research, and I am working with OAuth (signpost library) to gain access to user data from a web service which is also a part of the development process. I am able to flow through the common steps of OAuth, and I use a Uri (for callback to the app), and can get to the step where I invoke the devices browser, choose to verify my app, and the next step is SUPPOSED to redirect the browser BACK to the application....
Instead I get an error that reads something like "you do not have permission to open:
appSchema://appName?authorizationSensitiveInfo..." the appendages after the '?' are the oauth_token and oauth_verifier from the service (we can assume all steps up until the redirection are "correct").
Possible problems lie within the appSchema://appName
part. from my understanding this is the redirect URL which tells the Uri to use the phone's browser to locate my application and invoke the onResume() method. Where do the values for appSchema://appName
come from (defined in manifest? if so where?).
Why the problem with permission? Must I set permissions for my Uri to access my app? I'm lost...if you need code snippets to help me please reply, I didn't include any code because this is more like a concept I just missed...I'm not at my machine now but I can supply code if that would make things easier to understand. Really beating my head in here...
IN RESPONE TO A GREAT ANSWER HERE IS HOW I HANDLE MY ON RESUME
protected void onResume() {
super.onResume();
Uri uri = this.getIntent().getData();
if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
Log.d("StepGreenM", uri.toString());
String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
Log.d("StepGreenM", verifier);
try {
provider.retrieveAccessToken(consumer, verifier);
TOKEN = consumer.getToken();
REQUEST_SECRET = consumer.getTokenSecret();
Log.d("StepGreenM", TOKEN);
Log.d("StepGreenM", REQUEST_SECRET);
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
}
}
uri = getIntent().getData();
if (uri != null && CALLBACK_URI.getScheme().equals(uri.getScheme())) {
String token = settings.getString(HomeScreen.REQUEST_TOKEN, null);
String secret = settings.getString(HomeScreen.REQUEST_SECRET, null);
Intent i = new Intent(Intent.ACTION_VIEW); // Intent to go to the action view
try {
if(!(token == null || secret == null)) {
consumer.setTokenWithSecret(token, secret);
}
String otoken = uri.getQueryParameter(OAuth.OAUTH_TOKEN);
String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
// We send out and save the request token, but the secret is not the same as the verifier
// Apparently, the verifier is decoded to get the secret, which is then compared - crafty
// This is a sanity check which should never fail - hence the assertion
Assert.assertEquals(otoken, consumer.getToken());
// This is the moment of truth - we could throw here
provider.retrieveAccessToken(consumer, verifier);
// Now we can retrieve the goodies
token = consumer.getToken();
secret = consumer.getTokenSecret();
//Save it to a settings file
HomeScreen.saveAuthInformation(settings, token, secret);
// Clear the request stuff, now that we have the real thing
HomeScreen.saveRequestInformation(settings, null, null);
i.putExtra(USER_TOKEN, token);
i.putExtra(CONSUMER_SECRET, secret);
//GO TO APPLICATION
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
} finally {
startActivity(i); // we either authenticated and have the extras or not, but are going to the action view
this.setContentView(R.layout.indivaction);
finish();
}
}
}
Not sure what really makes this fall apart...but like I said it force closes when this method is invoked. I know it makes it past the redirect because I use an httpSniffer to check the messages to and from the server...
In order for the callback uri to work properly you need to add an intent filter similar to the following to your manifest in the activity you want to use it in.
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="appSchema" android:host="appName"/>
</intent-filter>
Now, if your activity is using singleInstance/singleTask, you should use something similar to the following:
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Uri uri = intent.getData();
String oauthToken = uri.getQueryParameter("oauth_token");
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
//...do what you need with the parameters
}
if not using singleTask or singleInstance, you can do
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Uri uri = intent.getData();
String oauthToken = uri.getQueryParameter("oauth_token");
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
//...do what you need with the parameters
}
I believe this should work.
Also, if I'm not mistaken, the callback url you provide should include the ?, so "appSchema://appName?"
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