Android Webview shouldOverrideUrlLoading method not working Android 10 and onwards - android

Android Webview shouldOverrideUrlLoading method not working Android 10 and onwards, when a click triggered for anchor tag href link, which is a valid URL. The below code is working fine for android 8 and 9, where it gets called. The override gets called, but not on android10 onwards. The new request based shouldOverrideUrlLoading(WebView, WebResourceRequest) is also working fine on Android 8 and 9, except android 10 and onwards. Tried to check release notes and it deidn't help.
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}

Related

Use shouldOverrideUrlLoading to handle commands on Android WebView

I'm new to Android, and I'm working on a simple WebView app.
I'm using shouldOverrideUrlLoading to handle some commands from my remote HTML to Android.
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(!url.startsWith("https://www.mywebsite.com)) {
switch (url) {
case "mycmd://app_logoff":
Toast.makeText(context, getString(R.string.logoff_ok), Toast.LENGTH_SHORT).show();
appLogoff();
break;
default:
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(urlWeb)));
}
}
return true;
I tested on my Android device (Motorola X Play) and it worked good! Is it safe to say that this will work on all android devices that matches the app minimum API level? Is this a good practice?
Since you are using shouldOverrideUrlLoading means you are implementing the custom WebViewClient and shouldOverrideUrlLoading should give your app a chance to take over the control when a new url is about to be loaded in the current WebView.
As per the developer documentation this API is added in API Level 1 so that basically means it is supported since long and should not be a concern as far as minimum API level.
I guess no one can surely say that it will work or not work on ALL devices unless actually tested on them. You may want to test them using Android emulators with different configurations such as different SDK/Platforms, API Level etc. to be double sure.
As a side note and caution, This method is not called for requests using the POST "method".
from webview android exapmle, shouldOverrideUrlLoading is used.
However, it is deprecated since api 24.
boolean shouldOverrideUrlLoading (WebView view, String url)
New replacement API with new parameter is here.
boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request)

How to handle shouldInterceptRequest parameter change in API21?

In API21 Google modified shouldInterceptRequest method to use WebResourceRequest request instead of String url.
Is there any way I could write a generic class extending WebViewClient and handle both methods?
My minimum API version is 18.
Thanks
Krystian
Google modified shouldInterceptRequest method to use WebResourceRequest request instead of String url
No, they added a second shouldInterceptRequest() method. Both are available in API Level 21+; the String variant is available on API Level 11+. While the String one is marked as deprecated, the String variant should be supported for quite some time, for backwards compatibility.
Is there any way I could write a generic class extending WebViewClient and handle both methods?
The built-in implementation of the WebResourceRequest version of shouldInterceptRequest() simply calls the String implementation of shouldInterceptRequest():
public WebResourceResponse shouldInterceptRequest(WebView view,
WebResourceRequest request) {
return shouldInterceptRequest(view, request.getUrl().toString());
}
(from the source code as of right now)
So, you have two choices:
Just override the String edition, if you do not need the WebResourceRequest, and it will be used on all relevant API levels.
Override both, knowing that the WebResourceRequest one will be used on API Level 21+ and the String edition will be used on API Levels 11-20.

Is default behavior of Android's WebView changed to open internally all links?

I noticed that with the last update of Google System WebView, all the links in my WebViews are opened in the view itself. But according to the documentation from google:
public boolean shouldOverrideUrlLoading (WebView view, String url)
Added in API level 1
Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url. This method is not called for requests using the POST "method".
I did not provide custom WebViewClient.
NOTE: The device that I noticed the problem was HTC One with the latest Google System WebView from June 8, 2015
I can reproduce the findings. Android System WebView 43.0.2357.121 exhibits the behavior that you describe, while the version I had on before upgrading to it did not.
I have filed a bug report on this and now need to do more testing and warn the world.
Thanks for pointing this out!
UPDATE
Here is a blog post that I wrote on this subject. Quoting myself from it:
My recommendation at the moment is:
Always attach a WebViewClient to your WebView
Always implement shouldOverrideUrlLoading() on the WebViewClient
Always return true to indicate that you are handling the event
Always do what your app needs to have done, whether that is loading
the URL into the WebView or launching a browser on the URL (rather
than returning false and relying on stock behavior)
Something like this static inner class appears to do the trick —
create an instance and pass it to setWebViewClient() on your
WebView:
private static class URLHandler extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (shouldKeepInWebView(url)) {
view.loadUrl(url);
}
else {
Intent i=new Intent(Intent.ACTION_VIEW, Uri.parse(url))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
view.getContext().startActivity(i);
}
return(true);
}
private boolean shouldKeepInWebView(String url) {
return(true); // or false, or use regex, or whatever
}
}
(where you would put your business logic in shouldKeepInWebView() to
determine whether or not a given URL should stay in the WebView
or launch a browser)
Seems to me this issue was resolved in 44.0.240.54.

shouldInterceptRequest is not called when running Android 4.3 or lower

I'm using a simple WebViewClient in a WebView in Android. I want to intercept requests when loading resources and thus I have overridden shouldInterceptRequest like this:
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
Log.d(TAG, "onInterceptRequest: " + url);
// Do something important if needed
//...
// else go on...
return super.shouldInterceptRequest(view,url);
}
The problem is that this doesn't work on all of my devices. On my Galaxy S4 with Android 4.4 it works all the time. On my Galaxy S2 with Android 4.1.2 it doesn't work at all. Any suggestions about this? The function shouldInterceptRequest is flagged as API level 11, so it should be safe on Android 3.0+
Update: I have now tested this on Android 4.3 and shouldInterceptRequest is not called on that device either. My targetSdkVersion is set to 19.
Update 2: More tests. It seems that shouldInterceptRequest is called when I'm using WebView::loadUrl, but not when I'm passing the html as a string using WebView::loadDataWithBaseURL.

How to handle a binary data response in WebView

My activity has an intent filter to pick up a specific url and open it in a WebView control, which brings user to an auth page (user name/password). After authentication is done user will get a binary stream response (file). Is there a way to handle that response and read data from the stream?
I tried to setup a custom WebViewClient with the overridden shouldOverrideUrlLoading method, but app doesn't get there.
#Override
mMyWebView.setWebViewClient(new CustomWebClient());
mMyWebView.loadUrl("http://xxx.xx.x.xx:xxxx/getCert");
...
private class CustomWebClient extends WebViewClient
{
#Override
public boolean shouldOverrideUrlLoading (WebView view, String urlConection)
{
// break point here doesn't stop debugger
return true;
}
}
neither works
mMyWebView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading (WebView view, String urlConection)
....
});
Server reacts on requests in the same way from both My app and build-in browser. Build-in browser starts to download file received in response, but my app doesn't do anything and doesn't hit breakpoint inside CustomWebClient.
This is a separate app just to test this piece nothing else interferes with it. INTERNET & WRITE_EXTERNAL_STORAGE permissions added.
EDIT: Mar 8
Gave up. Will go with httpClient.
Did you implement this method of WebView?
void setDownloadListener(DownloadListener listener)
Register the interface to be used when content can not be handled by the rendering engine, and should be downloaded instead.

Categories

Resources