I try to call the browser of my device loading a page inside a WebView that contains:
window.open(
'http://www.stackoverflow',
'_blank'.
);
I need to do this from the html that is loaded into the WebView
but i have no success, any idea!?
There are several things you need to do in your app:
Use setJavaScriptCanOpenWindowsAutomatically as #ajpolt says. This will allow window.open to not fail.
Enable setSupportMultipleWindows. This makes WebView to actually attempt opening a new window. Otherwise, it will be opening the URL in the same WebView.
Hook up to WebChromeClient.onCreateWindow callback and create a new WebView instance there. For this new instance, you need to set WebViewClient that will launch the intent from shouldOverrideUrlLoading.
Below is sample code:
WebView webView = (WebView)findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setSupportMultipleWindows(true);
webView.setWebChromeClient(new ChromeClient());
And this is the ChromeClient:
class ChromeClient extends WebChromeClient {
#Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
WebView tempWebView = new WebView(MainActivity.this);
tempWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
startActivity(browserIntent);
return true;
}
});
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(tempWebView);
resultMsg.sendToTarget();
return true;
}
}
You are probably missing a setting on your webview.
Try using setJavaScriptCanOpenWindowsAutomatically in your settings, like this:
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
Related
I have a web page, which if loaded inside a webview, then the page should reload in a mobile web browser instead of inside the webview.
Basically I want to send the user to a browser from the webview.
Is this possible using javascript or jquery?
Here is example for dialog or popup in webview :
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Title here");
WebView wv = new WebView(this);
wv.loadUrl("http:\\www.google.com");
wv.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
alert.setView(wv);
alert.setNegativeButton("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
alert.show();
In an Android activity I am displaying a webview.
WebView myWebView = (WebView) findViewById(R.id.webView1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("file:///android_asset/html/cloud.html");
The webview loads a local HTML file that builds a cloud of keywords with a javascript file. (source: http://www.goat1000.com/tagcanvas.php)
<script src="tagcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
try {
TagCanvas.Start('myCanvas','tags',{depth: 0.8, maxSpeed: 0.03});
} catch(e) {
// something went wrong, hide the canvas container
document.getElementById('myCanvasContainer').style.display = 'none';
}
The keywords are generated from a list of HTML links defined in the HTML file
<div id="tags">
<ul>
<li>keyword1</li>
<li>keyword2</li>
<li>keyword3</li>
</ul>
</div>
When a user taps on a link, instead of staying in the webview and going to the corresponding location, I would like him to start a new Android activity, so obviously with Android code
I have found resources showing an example of how to make Android and Javascript "communicate" with an interface but I didn't manage to make it work in my case.
Edit:
My implementation thanks to the answer of Vlad
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Intent intent = new Intent(Act1.this, Act2.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //ugly solution to avoid starting 2 activities, not ideal but it works
startActivity(intent);
return true; //I always return true because I never want to open an HTML link
}
});
You can set a custom WebViewClient to the WebView, and intersect url loading in it:
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// check the URL, and do whatever you need to do according to the URL
// return true; // if you handled URL, and WebView should not load it
return false; // for the WebView to load the URL
}
});
I have an Android webview with a page that redirects to another page, using location.replace(url).
Lets say that I have page "A" that redirects to page "B" (using location.replace). When pressing "back" button from page "B", the page returns to page "A", which redirects it to page "B" again.
When I debug the history api (history.length), I can clearly see that on page "B" the length has incremented in "1" (only on Android 4.X webview. On iOS / web browser / Android 2.X it remains the same), which is a bug! (location.replace shouldn't change history.lenght!)
I work with Yaniv on this project and we found the cause of the problem, it was introduced when we tried to add mailto: links handling according to this answer.
The answer suggested using the following extending class of WebViewClient:
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(MailTo.isMailTo(url)){
MailTo mt = MailTo.parse(url);
// build intent and start new activity
return true;
}
else {
view.loadUrl(url);
return true;
}
}
}
The problem was that explicitly telling the WebViewClient to load the URL and returning true (meaning "we handled this") added the page to the history. WebViews are quite capable of handling regular URLs by themselves, so returning false and not touching the view instance will let the WebView load the page and handle it as it should.
So:
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(MailTo.isMailTo(url)){
MailTo mt = MailTo.parse(url);
// build intent and start new activity
return true;
}
else {
return false;
}
}
}
function locationReplace(url){
if(history.replaceState){
history.replaceState(null, document.title, url);
history.go(0);
}else{
location.replace(url);
}
}
Try this way..
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView mainWebView = (WebView) findViewById(R.id.webView1);
WebSettings webSettings = mainWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mainWebView.setWebViewClient(new MyCustomWebViewClient());
mainWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mainWebView.loadUrl("file:///android_asset/www/A.html");
}
Or get help from this and this link
I'm using mWebView.addJavascriptInterface(this, XXX) to let java
enter code herescript be executed on a webview.
The problem comes when the web page that I'm browsing sends a redirect.
I'm able to capture it an display the new URL in the same webview but javascript will not work.
The only solution that I've found is to create a new intent that load the new page on a new Activity.
public class QBrowser extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.qbrowser_main);
mWebView = (WebView) findViewById(R.id.webview);
webSettings.setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new MyWebChromeClient());
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// BEGIN: THE WORK AROUND I DONT LIKE
Intent intent = new Intent("com.bcnquark.client.qbrowser.QBROWSER");
intent.putExtra("URL", url);
startActivity(intent);
finish();
// END:THE WORK AROUND I DONT LIKE
return true;
}});
Intent intent = getIntent();
String url = intent.getStringExtra("URL");
mWebView.addJavascriptInterface(this, "XXXX");
}
mWebView.loadUrl(url);
}
}
I have a WebView in which i display web content which i have no control over. The content displays fine, but have links which spawn a popup window. The javascript function that does that looks like this:
function getEntry(id) {
var win = window.open('', 'Booking',
'resizable=yes,scrollbars=yes,status=no,width=500,height=400');
win.document.location = '/some/url/1-' + id ;
}
I can't easily change this, and if the people responsible for the page i download would change it, i guess my app would fail miserably...
My WebView setup in the activity looks like this:
_webview = new WebView(this);
setContentView(_webview);
final Activity activity = this;
_chromeClient = new MyChromeClient();
_webview.setWebChromeClient(_chromeClient);
//I experimented with changing user agent, in case that would have any effect, it didn't...
_webview.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1");
_webview.setWebViewClient(new MyWebViewClient());
_webview.getSettings().setJavaScriptEnabled(true);
_webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
_webview.getSettings().setSupportZoom(true);
_webview.getSettings().setBuiltInZoomControls(true);
_webview.getSettings().setDomStorageEnabled(true);
//Cache settings...
_webview.getSettings().setAppCacheMaxSize(1024*1024*8);
_webview.getSettings().setAppCachePath("/data/data/com.your.package.appname/cache");
_webview.getSettings().setAllowFileAccess(true);
_webview.getSettings().setAppCacheEnabled(true);
MyWebClient:
private class MyWebViewClient extends WebViewClient {
#Override
public void onLoadResource(WebView view, String url) {
Log.d("MyWebViewClient",url);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
showProgressDiag();
Log.d("MyWebViewClient","shouldOverride... : " + url);
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url){
hideProgressDiag();
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
if(failingUrl.equals("file:///android_asset/html/error.html")){
hideProgressDiag();
Toast.makeText(_context, "Error! Check internet connection, or try again later...", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(_context, failingUrl, Toast.LENGTH_SHORT).show();
view.loadUrl("file:///android_asset/html/error.html");
}
}
}
MyChromeClient:
private class MyChromeClient extends WebChromeClient{
#Override
public void onProgressChanged(WebView view, int progress) {
Pdiag.setProgress(progress * 100);
}
}
When clicking one of the links that points to the javascript function all that happens is that the WebView turns grey, without going through shouldOverrideUrlLoading(). When i hit the back key the app exits, meaning that nothing was placed in the nav history of the WebView. Sometimes nothing happens, but then the shouldOverrideUrlLoading() do run and from a Log.d() i can see that the correct URL for the popup has been given to the WebView.
The thing is, on very rare occasions it shows up fine, but i have no clue how to reproduce it, and wether it actually shows in a popup.
I'm lost... And quite frustrated... Thinking of watching a bad sitcom instead :(
EDIT:
Actually, maybe the URL wasn't all that correct after all... In Firefox the URL ends with "X<<<<" but in my Log.d() output it ends with "X%3C%3C%3C%3C"... I'll investigate if i could change that...
EDIT 2:
Nope, didn't do anything... The URL is identical to the one in Firefox...
First of all, you need to set the following settings on your WebView:
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);
Then you need to attach a WebChromeClient that overrides onCreateWindow. Your implementation of this method can create a new web view, and display it inside a dialog:
webView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
WebView newWebView = new WebView(MyActivity.this);
WebSettings webSettings = newWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
// Other configuration comes here, such as setting the WebViewClient
final Dialog dialog = new Dialog(MyActivity.this);
dialog.setContentView(newWebView);
dialog.show();
newWebView.setWebChromeClient(new WebChromeClient() {
#Override
public void onCloseWindow(WebView window) {
dialog.dismiss();
}
});
((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);
resultMsg.sendToTarget();
return true;
}
});
Don't forget to set the new web view to the resultMsg, send it to its target and return true, as mentioned in the API documentation.
Please check with adding this -
getSettings().setSupportMultipleWindows(true);