I have a problem with WebView. My app has build in help files made with html in local assets. And I show html file with WebView.
My problem is, WebView's goBack() function can't go back to previous page when it tries to return to bookmarked position.
For example:
Page1 has link to bookmark1 in Page1.
And Page1 has link to Page2.
Showing Page1 and hit link to Page2, then goBack() can go back to Page1. Fine.
Showing Page1 and hit link to bookmark1, and then hit link to Page2, then goBack() can't go back to page1. WebView shows error like it can't find url with #bookmark1.
I suspect WebView is not handing viewing history for local files. I'm using OS 4.0.3.
Any solutions?
I have found a (compromising) solution for this issue. This issue was discussed here and one solution can be found here (Japanese page, sorry). In my case, after knowing it's a bug in some range of Android OS, going back to previous page (not to exact anchor position) is fine. So I ended up with next code.
webView = (WebView)findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient()
{
// https://stackoverflow.com/questions/6542702/basic-internal-links-dont-work-in-honeycomb-app
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
super.onReceivedError(view, errorCode, description, failingUrl);
String url = failingUrl;
int index = url.indexOf("#");
if (index != -1)
{
url = url.substring(0, index);
}
webView.loadUrl(url);
}
});
With this code when it can't go back to previous page with anchor, it goes back to previous page without anchor. I compromised with it. I tried to make it better with other solutions using Java Script but did not work.
Related
My Android app uses a WebView to let the user navigate around the Internet, but occasionally it encounters a site that navigates using its own funky schema. For example, if you search for "aliexpress", the app will take you to the site's Home page just fine.
However, if you select any of the buttons on the top, WebView throws an error:
All I needed to do was call shouldOverrideUrlLoading() as follows:
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri current_page = request.getUrl();
if (!current_page.toString().startsWith(("http://")) && !current_page.toString().startsWith(("https://"))) return true;
return false;
}
I have a page that displays a news story, the page's content is loaded from a json response which is cached, the problem occurs when the uses is not connected to the internet and tries to access the story, the story loads correctly but the iFrame shows an ER_INTERNET_DISCONNECTED error.
We want to still be able to use the offline feature but if the iFrame has any error remove it from the page, is there anyway to do this ?
I've uploaded a screenshot if that helps
enter image description here
webView.setWebViewClient(new WebViewClient() {
#Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// either load a new url, or show a popup to the user
webView.loadUrl("file:///android_asset/custom_error.html");
} });
You can decide for yourself what to do in the onReceivedError
There is a rather specific webpage loaded into WebView which URL is like http://www.site.com/mob/ (basically a mobile-optimized web page). This webpage display 25 articles only and on the bottom is a button "More articles".
When a user presses it, I catch URL http://www.site.com/Web/MobHomeItems.aspx?page=N (where N is 2, 3, 4...) and after that another 25 items have been loaded on the same screen.
Now, when I click on some article and go to article details, and later return to the page via the Back key, the WebView forgets how many articles have been loaded and simply loads the default page with 25 displayed articles. Imagine how frustrating this would be to a user if he came to 100th article.
I tried overriding many methods in WebClient and in WebChromeClient, but so far I have been unable to load N number of pages loaded via "More Articles" button. For example, I first thought this would help, but it did not.
#Override
public void onLoadResource(WebView view, String url) {
//http://www.site.com/Web/MobHomeItems.aspx?page=2
if (url.contains("?page=")) {
//save this URL for later and on return from
// article details, pass it to LoadResource()
super.onLoadResource(view, url);
}
Then I tried similar approach with other method - basically remembering how many pages have been loaded on the main page, and then on return from article details, simply tell webview to load this URL.
Can anyone help me? How to append loaded pages to the main page? Should I use JavaScript here maybe?
PS. Loading mentioned URL http://www.site.com/Web/MobHomeItems.aspx?page=N does not help as it loads this concrete page into the WebView only, and it does not append this Nth page to the main page.
EDIT
As #Raghunandan asked, I do not have problems loading back to 1st page (?page=1). This is default when user presses Back button on article details. I want to load to the page where a user was before pressing article details. If he was on ?page=100, I want to load back to that page e.g. I want to have 25x100 articles open. Again, default is always "open 25 articles or ?page=1 or http://www.site.com".
Override the method shouldOverrideUrlLoading of WebViewClient.
like this:
public boolean shouldOverrideUrlLoading (WebView view, String url) {
if (url is kind of article detail) {
WebView newOne = new WebView(); // create a new Webview for displaying the details.
view.setVisibility(View.INVISIBLE); // hiding current page (article list)
return true; // To tell the WebView we have process this url.
}
return false;
}
The user click one link of article's detail.
shouldOverriderUrlLoading would be triggered.
We created one new WebView to open the url.
Hiding current page
The user reading artical
The user click back key, close the newOne WebView then make the
previous WebView visible.The article list will show up immediately and remained the old statement
.
There is a another way to do this.
The WebSettings has a private method "setPageCacheCapacity" , the default value is 0 , you could enlarge it (may be 5).
You can access this method by using reflection of java.
The method can enable WebView to cache more than one document. In the other word. when user press the back key, the WebView will go back to the older document.
Probably it will have a simple solution but I've read many threads here but no way.
In a ListView, if i tap on a row it opens a new Activity. In that activity I make an httpget and I create an html string with what I need from that httpget (a portion of the web page retrieved).
So I simply make a loadDataWithBaseURL("http://base_path.com/", html, mime, encoding, null).
It works as expected and I view the web page with links and images.
Now the problems come... If I tap on an image I see the large image in that windows but once i press the "back" on the phone I see a white page. I know that it is caused by the "null" argument but... what I should put to see the html page again? I tried to put "html" instead of null but I see the html code inside the webview!
This is my onKeyDown to override the back button:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the BACK key and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
// If it wasn't the BACK key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
I found some information at this answer:
Android: WebView's method goBack() shows a blank page
You need to provide a URL to back into when you call
loadDataWithBaseURL("http://base_path.com/", html, mime, encoding, null);
You are passing null so defaults to 'about:blank'. Try this instead:
String baseUrl = "http://base_path.com/";
loadDataWithBaseURL(baseUrl, html, mime, encoding, baseUrl + filename);
As a workaround i made the following activities.
removed the onKeyDown function
removed the myWebView.setWebViewClient(new WebViewClient());
In this way the image loads in the default Android browser and i can close it with the back button.
It is not fine to go outside the WebView but i had no other choices.
As Gadgeteer mentioned passing null on loadDataWithBaseURL() will add the 'about:blank' into the stack of webview history.
To avoid this problem, I clear webview history as soon as I call loadDataWithBaseURL() by calling
webview.clearHistory()
as per document
public void clearHistory ()
Tells this WebView to clear its internal back/forward list.
If you call clearHistory() after calling loadDataWithBaseURL() the webview not go back to blank page and canGoBack() also return false; because there is no back stack in the webview after clearHistory()
Try this:
webview.loadUrl("file:///android_asset/your_html.html");
instead of your loadDataWithBaseURL
I'm making an Android application that, among other things, shows websites in a webview. As far as I understand, the webview automatically shows a cached version of the page if a connection can't be established.
Is there any way to find out if the page shown has been fetched from the server or cache?
Maybe even how old the cached page is.
This is to be able to notify the user if he/she is viewing old information.
You could try a hack - at first set WebView's cache mode to WebSettings.NO_CACHE and load the URL. Then, create a custom WebChromeClient like this:
final String urlToLoad = "http://www.my-url.com";
webview.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl)
{
if (view.getSettings().getCacheMode() == WebSettings.LOAD_NO_CACHE && urlToLoad.equals(failingUrl))
{
view.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
view.loadUrl(urlToLoad);
return;
}
else
if (urlToLoad.equals(failingUrl))
{
// cache failed as well, load a local resource as last resort
// or inform the user
}
super.onReceivedError(view, errorCode, description, failingUrl);
}
});
webview.loadUrl(urlToLoad);
Since the WebView work like the browser the answer is no.
There are some hacky way to detect that situation.
Or an alternative solution would be preventing the page from being cached (see WebView documentation)