Reputation: 3067
I have a problem with implementing user authentification in a WebView.
As API Docs say, I need to load URL "http://example.com/?key=abc" then User enters his login & password and then he's redirected to webpage "myapp://token#access_token=123456".
All I need is to load this in a WebView and return to my application with that "123456" token. The first problem is that WebView doesn't support custom protocols and it gives me an error "ERR_UNKNOWN_URL_SCHEME".
Second problem is that I don't fully understand how to return to my application with page data.
In AndroidManifest.xml I have this:
<activity
android:name="(appname)"
android:label="@string/app_name"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="myapp"
android:host="token"/>
</intent-filter>
</activity>
In Main.java file I have the following code:
Intent i = new Intent(Main.this, LoginWebViewActivity.class);
startActivityForResult(i, 1);
and in LoginWebActivity.java I have the following code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webviewact);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://example.com/?key=abc");
}
I see one fast solution: Open this link in external browser, however, I don't understand how can my application get data from external browser.
Upvotes: 0
Views: 4872
Reputation: 10278
This is not a "web page":
myapp://token#access_token=123456
That is possibly a URI that you could filter on if you do it properly. You need to implement your own URI with an IntentFilter
like this:
see this post:
How to implement my very own URI scheme on Android
EDIT:
To explain - you are sending a "login" request. Then you say you are "redirecting" the client to
myapp://token#access_token=123456
You can't tell the client to "redirect" to a non-URL webpage. The WebView
client is an "http" client - it does not accept data schemes / mime types that it does not recognize. So your "redirect" is failing.
When you do the page request, the response should be the URI not a redirect. You can parse the response data to see if you got this response (vs a failed login) and if you did, you can launch a new Activity. Simple as that.
There is an answer here that suggests that you override shouldOverrideUrlLoading
which is also acceptable. In this case, we're assuming you are doing a client-side redirect, in which case this method will allow you to capture the authentication response, parse it for the data that you need, then you can launch whatever URL or activity you want.
To explain further, the XML data scheme is only useful for Intent
s. Your WebView
is responding internally - no intent is sent. You have to get the HTTP response, parse it, then broadcast an Intent
to get that portion of your code to work.
Upvotes: 0
Reputation: 15379
You should not need to implement a custom scheme. You should be passing that callback URL into the webpage, and then you look for and intercept that callback in your code by handling shouldOverrideUrlLoading
:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("http://myapp/token#access_token=")) {
// Parse the token fom the URL and close the webview
return true;
} else {
return super.shouldOverrideUrlLoading(view, url);
}
}
});
Upvotes: 2