I am developing an app which uses OAuth for authentication but I have a little problem handling OAuth callbacks.
THE AUTHENTICATION
My app has a
First of all in your manifest, set these properties to your activity that launches the WebView
android:launchMode="singleInstance"
and add an intent filter to that as
<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="oauth-testing" />
</intent-filter>
then in your code when the user clicks on the login button
mReqToken = mTwitter.getOAuthRequestToken(CALLBACK_URL);
WebView webView = new WebView(this);
webView.requestFocus(View.FOCUS_DOWN);
webView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (!v.hasFocus()) {
v.requestFocus();
}
break;
}
return false;
}
});
webView.loadUrl(mReqToken.getAuthenticationURL());
mainLayout.removeAllViews();
mainLayout.addView(webView);
Here the callback url is
private static final String CALLBACK_URL = "oauth-testing:///";
and you are creating a dynamic webview and displaying to the user. And after logging in the webview is closed and the code comes to the onNewIntent()
. You need to implement your functionality after logging in there.
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
dealWithTwitterResponse(intent);
}
private void dealWithTwitterResponse(Intent intent) {
Uri uri = intent.getData();
System.out.println("URI=" + uri);
if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
authoriseNewUser(oauthVerifier);
}
}
I know I have added a lot of code snippet, some of which might not be relevant, but i hope it will help someone someday.
As you have the Object of WebView so you can overload it and then handle the url on which you wana navigate to your Activity,in these two way.
private class MyWebView extends WebViewClient{
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
{
Uri uri = request.getUrl();
return shouldOverrideUrlLoading(uri.toString());
}
private boolean shouldOverrideUrlLoading(final String url)
{
Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
//your code to handle the url for navigation will go here
try{
if(url.contains("yourcondition")){
//1st way to handle
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}else{
//2nd way
Intent intent = new Intent(YourActivity.this,NewActivity.class);
//you can set the data
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}
}catch(ActivityNotFoundException e) {
Log.e(LOGTAG,"Could not load url"+url);
}
return false;
// return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false.
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
try {
if(url.contains("yourcondition")){
//1st way to handle
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}else{
//2nd way
Intent intent = new Intent(YourActivity.this,NewActivity.class);
//you can set the data
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}
} catch(ActivityNotFoundException e) {
Log.e(LOGTAG,"Could not load url"+url);
}
return false;
}
}
you can set the mWebView.setWebViewClient(new WebViewClient());
which is default but by
just adding a default custom WebViewClient will only allow the WebView to handle any loaded urls itself i.e. within the webView instead of browser.
but if you overload by passing above class MyWebView
like mWebView.setWebViewClient(new MyWebView());
then you can control the the loading of url same thing u can achive
myWebView.setWebViewClient(new WebViewClient(){
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
{
Uri uri = request.getUrl();
return shouldOverrideUrlLoading(uri.toString());
}
private boolean shouldOverrideUrlLoading(final String url)
{
Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);
//your code to handle the url for navigation will go here
try{
if(url.contains("yourcondition")){
//1st way to handle
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}else{
//2nd way
Intent intent = new Intent(YourActivity.this,NewActivity.class);
//you can set the data
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}
}catch(ActivityNotFoundException e) {
Log.e(LOGTAG,"Could not load url"+url);
}
return false;
// return true; // this True means that application wants to leave the WebView and try to go to browser and handle the url itself, otherwise return false.
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
try {
if(url.contains("yourcondition")){
//1st way to handle
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}else{
//2nd way
Intent intent = new Intent(YourActivity.this,NewActivity.class);
//you can set the data
intent.setData(Uri.parse(url));
YourActivity.this.startActivity(intent);
}
} catch(ActivityNotFoundException e) {
Log.e(LOGTAG,"Could not load url"+url);
}
return false;
}});
In case you don't have control of webview object then this is not the solution i will update once i will solve this.
Well, first you may need call the URL that is provided by your service provider, if there is any redirect exist you will get HTTP status code 3xx. Next you can try to call the actual URL if there is any redirect exist. For normal HTTP response, you will get HTTP 2xx status code.