I am facing a strange issue.
In my application, I need to load a static html file based on clicked button in a WebView from assets folder.
Now among 5 html files, one html file contains 15 static links. These links need to redirect user to the mentioned url in a mobile browser. I have used target="_blank" for that purpose as follows in my html file.
<div class="lid">Railway Reservation </div>
Now, this works fine in a sample application with a simple WebView without any WebViewClient added to it.
But I need a WebViewClient for my other functionalities. So at that time target="_blank" is totally ignored. And the url is opened in a WebView itself.
I found a workaround, that I can use shouldOverrideUrlLoading as follows:
myWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
if(url.equalsIgnoreCase("https://www.irctc.co.in/"))
{
view.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
else
return super.shouldOverrideUrlLoading(view, url);
}
});
So this is opening that particular url in a default browser.
So basically my questions are:
Why is target="_blank" ignored while we use WebViewClient? And is there any other workaround for this issue? Because I have 15 links, which I would need to compare. I can't load all urls in a new browser, as there are a few links, which need to be opened in a same WebView, too.
I have an idea for a workaround. Replace all links which should been opened in a new window with a custom schema. Then you can handle that by your own.
For a minimal interruption set also a custom theme and handle all configuration changes:
<activity android:name="com.example.LinkHandler"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="#android:style/Theme.Translucent">
<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="your.link.handler.schema"/>
</intent-filter>
</activity>
Then in your link handler you can read the url by using getIntent().getData().
Please also keep in mind that you should handle http and https, I skipped that in my short example above.
Here is an JavaScript example how to rewrite the urls:
for(var i=0; i<document.links.length; i++) {
if(document.links[i].target == "_blank") {
document.links[i].href = "your.schema.for."+document.links[i].href;
}
}
<ul>
<li>Test 1</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>
Related
I am developing an android app with a web app loading on WebView. I want to invoke the web app button actions. I have implemented some changes on webpage to invoke native methods as shown below.
mWebview.addJavascriptInterface(new Object() {
#JavascriptInterface // For API 17+
public void callNativeHome() {
Log.d("btnsetup", "btnsetup");
}
}, "btnsetup");
But now I can't make any changes on web end as it's not my web screen. How I can access the button click events by ID or class name?
Web access is mandatory to Bind JavaScript code to Android code.
Android:
val webView: WebView = findViewById(R.id.webview)
webView.addJavascriptInterface(WebAppInterface(this), "Android")
Web:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
You can simply follow Bind JavaScript code to Android code.
Another workaround is to find the navigation URL. You can check/compare the redirection URL called after clicking that button.
For more information, you can check Handle page navigation in webview.
I am building an android application. I am showing external webpage in webview. I have followed these steps:
Load external website in webview. For example example.com, it loads fine in webview
There is an option in example.com site to launch Dialer app on button click. Here is the code.
<div class="center">
<input type="image" src="btn.png" onclick="location.href='tel:0000';"/>
</div>
When I go to example.com from mobile browser and click on button, it can launch Dialer app with phone number
When I click from webview it shows this error
Web page not available
The web page at tel:0000 could not be loaded because:
net::ERR_UNKNOWN_URL_SCHEME
I do not know what is went wrong. Any clue will be helpfull.
NB: I am using real phone number (here it is 0000).
Thank you
You should set a WebViewClient to the WebView and than override shouldOverrideUrlLoading method as follow:
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if (request.getUrl().toString().startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_DIAL, request.getUrl());
view.getContext().startActivity(intent);
}
return super.shouldOverrideUrlLoading(view, request);
}
});
I'm trying to build a simple localStorage example using android webview. I'm having some trouble when i close the app. Everytime i start the app, values stored in localStorage disappear. I googled it and couldn't find a proper solution. Here I put my HTML, Java, Manifest code samples. Any help will be appreciated.
HTML :
<!DOCTYPE html>
<html>
<head>
<script>
function clickCounter()
{
if(typeof(Storage)!=="undefined")
{
if (localStorage.clickcount)
{
localStorage.clickcount=Number(localStorage.clickcount)+1;
}
else
{
localStorage.clickcount=1;
}
document.getElementById("result").innerHTML="You have clicked the button " + localStorage.clickcount + " time(s).";
}
else
{
document.getElementById("result").innerHTML="Sorry, your browser does not support web storage...";
}
}
</script>
</head>
<body>
<p><button onclick="clickCounter()" type="button">Click me!</button></p>
<div id="result"></div>
<p>Click the button to see the counter increase.</p>
<p>Close the browser tab (or window), and try again, and the counter will continue to count (is not reset).</p>
</body>
</html>
JAVA:
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setDatabasePath(this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath());
webView.loadUrl("http://www.example.com/sample.html");
setContentView(webView);
MANIFEST:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Permission lines are placed under tag but outside the tag
and here is the scenario:
-turn off the internet connection of the mobile device
-start the app
-open the page inside the webview
-tap the button several times
-close the app (close it inside the task manager)
-turn on the internet connection of the mobile device
-start the app
-open the page
-tap button several times and it counts from beginning
you can create different scenarios while trying. The main problem is how to set the webView to use localStorage properly?There is something that i'm missing about webview.(this error does not occur when you try it on the chrome browser or any other browser)
This seems like a bug of webview. I was actually trying to open 3 different pages inside a webview and I was loosing localStorage data. I splitted this activity into 3 activities that each of them opens only one page. And the problem disappeared.
I am new to Stack Exchange and Andorid development.
I am working on Android webview. I have the following code in my activity class.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WebView wv;
WebSettings ws;
try {
wv = (WebView) findViewById(R.id.webview);
ws = wv.getSettings();
ws.setJavaScriptCanOpenWindowsAutomatically(true);
ws.setJavaScriptEnabled(true);
wv.clearCache(true);
wv.loadUrl("http://<ip address>:<port>/<context>");
} catch (Exception e) {
e.printStackTrace();
}
}
in layout-main.xml:
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
in AndroidManifest.xml:
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".POCActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
In the url I have index.html with the following code:
<!DOCTYPE html>
<html>
<head>
<title>Contact Example</title>
<script type="text/javascript">
alert("Start");
</script>
</head>
<body>
<p>Database 1</p>
<div id="test"></div>
</body>
</html>
Working Environment:
- Eclipse indigo
- Android SDK min version 10
- Build Target 2.3.3
But the android code is working only once i.e. when I create a new android project and run the same, I can see the javascript alert appearing. From next time the javascript alert is not displayed. Even is any text changes(Say I modified "Database 1" to "Database 2") in the html page is also not displayed.
I tried the following:
- Cleared appcache
- Uninstalled the application and then ran the project again
- Cleared
Please let me know what I am doing wrong here. Any help will be much appreciated.
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
Used these on my code and then my alert() worked pefectly
This is a very old question, but I recently encountered the same problem and would like to share the solution to anyone who come across this later.
You will need to assign a custom WebChromeClient to your WebView to handle the alert.
mWebView.webChromeClient = object : WebChromeClient() {
override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
val alertDialog = AlertDialog.Builder(context)
.setMessage(message)
.setPositiveButton("OK") { dialogInterface, _ ->
dialogInterface.dismiss()
result?.confirm()
}
.setOnCancelListener { result?.cancel() }
.setCancelable(true)
.create()
alertDialog.setCanceledOnTouchOutside(true)
alertDialog.show()
//Here AlertDialog is just an example. You can also simply show a Toast.
//But remember to call JsResult.confirm() or JsResult.cancel()
return true
}
}
You need to call either JsResult.confirm() or JsResult.cancel() to notify your WebView whether the user confirmed or canceled the alert dialog. Otherwise, the WebView would assume an alert dialog is still showing(blocking the UI) and won't allow a new one to be shown.
I have a WebView which may contain data that appears to be getting "auto linked". Something that looks like an email address is becoming clickable, even though it's now within an <a> tag or has an onclick attribute. How do I disable this auto-linking?
I've looked thorugh the WebView docs, as well as the WebSettings docs, but didn't seem to see anything that mentions this behavior.
alt text http://beautifulpixel.com/assets/5554_Fast-20100706-110228.png
I know this is a bit late, but for future reference, this might be a solution that will work regardless if the links are auto created or defined in the <a>-tag.
myWebView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// return true; // will disable all links
// disable phone and email links
if(url.startsWith("mailto") || url.startsWith("tel")) {
return true;
}
// leave the decision to the webview
return false;
}
});
To do all the email addresses, add a meta tag:
<meta name="format-detection" content="email=no" />
You can also disable physical address and telephone detection:
<meta name="format-detection" content="telephone=no" />
<meta name="format-detection" content="address=no" />
In my own application, though, I needed PhD's solution to prevent only one email from being linked.
I had the same problem, tried this:
<a onClick=\"return false;\">jorgesys#elnorte.com</a>
it did not worked.
Then tried this:
<a href='javascript:void(0);'>800-644-9737</a>
and it did the trick
Hi Squeaggy why you do want to eliminate that funcionality from the webview, but well a tricky way would be including onClick="return false;" in the anchor tag that contains the email or URL.
<a onClick=\"return false;\">jorgesys#elnorte.com</a>
That appears to be unchangeable functionality of the WebView.
You could do the opposite of this Is there any way to have WebView auto-link URLs and phone numbers in Android? and create a javascript link stripper (instead of the proposed link injector there).
Not sure what else would work for this.