I am trying to load 2 URL's in a webview, one after the other, and grab their html. My code looks as following:
final WebView webview = (WebView) findViewById(R.id.showInfo_webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webview.loadUrl("javascript:window.HTMLOUT.showHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
webview.loadUrl(response);
webview.loadUrl(response2); <--
class MyJavaScriptInterface {
#JavascriptInterface
public void showHTML(String html) {
...
}
}
In showHTML I'd have a counter so I can distinguish between the first and the second call. However, showHTML gets called only once. Why is that? Do I need to recreate the webview entirely?
I tried calling webview.reload() after the 2nd loadUrl but then it looks like the 2nd page is loaded twice?
EDIT: I need to process the 1st URL html to obtain the 2nd URL.
String[] urls = {"http://www.demo.com", "http://www.fb.com"};
int delay = 50 * 1000;
Handler handler = new Handler();
for(int i = 0; i < urls.length; i++) {
webview.setWebViewClient(new WebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
MyRunnable runnable = new MyRunnable(urls[i], webview);
handler.postDelayed(runnable, delay);
delay = delay + 50 * 1000;
}
private class MyRunnable implements Runnable {
private String url;
private WebView wv;
public MyRunnable(String url, WebView wv) {
this.url = url;
this.wv = wv;
}
public void run() {
webview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webview.loadUrl("javascript:window.HTMLOUT.showHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
});
}
}
I worked around it by creating an activity which basically only has the webview. I startActivityForResult twice in a row and that's it. It's certainly not elegant but it works.
Related
i wanna load a second url after the first url finish loading but it's not working ,
why he stay only on first url ?
here is my code :
webView = (WebView) findViewById(R.id.wvDisplay);
// Enable Javascript
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.setWebViewClient(new MyBrowser());
String url ="http://www.google.com";
if (!url.startsWith("http://") && !url.startsWith("https://"))
url = "http://" + url;
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.loadUrl(url);
}
private class MyBrowser extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String url2="http://www.facebook.com";
webView.loadUrl(url2);
}
}
it's not working, if any have idea please help me. Thanks in advance.
This code makes what you need & fixes your activity memory leak (inner classes should be static in activities or else is a memory leak)
private static class MyBrowser extends WebViewClient {
private String[] mStrings = {"http://www.facebook.com"};
private int index = 0;
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (index < mStrings.length)
view.loadUrl(mStrings[index++]);
}
}
I have an activity A which has a button. On clicking this button, activity B launches. Activity B has WebView inside an xml layout which loads HTML page stored locally on the device. The whole webpage consist of several CSS(heavy material) and jsons(large in size). At this time the RAM usage is around 90MB. HTML have input fields both text and numeric in it. The problem is after opening and closing the webview 3-4 times, when I click on the input field the keyboard become invisible.
Click here for screenshot
This is my activity code.
public class LaunchActivity extends Activity {
WebView webView;
private final int FILECHOOSER_RESULTCODE = 1;
private Uri mCapturedImageURI = null;
public String mCameraPhotoPath;
String webViewUrl;
public String mMediaType;
public int flag = 0;
public File imageStorageDir;
Bundle bundle;
String mode;
public ProgressDialog progDailog;
int questionToBeLaunch;
Project project;
public void onBackPressed() {
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.launch_survey);
// getting data from intent and creating the url to load.
webView = (WebView) findViewById(R.id.webView1);
setWebViewProperties();
Map<String, String> header = new HashMap<String, String>(2);
header.put("Pragma", "no-cache");
header.put("Cache-Control", "no-cache");
webView.loadUrl(webViewUrl, header);
}
public void setWebViewProperties(){
JavaScriptInterface jsInterface = new JavaScriptInterface(this);
// Javascript enabled on webview
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.addJavascriptInterface(jsInterface, "interface");
// Other webview options
webView.getSettings().setLoadWithOverviewMode(true);
//webView.getSettings().setUseWideViewPort(true);
//Other webview settings
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setScrollbarFadingEnabled(false);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAllowFileAccessFromFileURLs(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setSupportZoom(true);
progDailog = new ProgressDialog(LaunchSurvey.this);
//Load url in webview
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progDailog.setMessage("Loading...");
progDailog.setCanceledOnTouchOutside(false);
progDailog.setCancelable(false);
progDailog.show();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView.clearCache(true);
}
});
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
// webView.setOnTouchListener(null);
webView.removeAllViews();
webView.clearCache(true);
webView.clearHistory();
// clearCache(getApplicationContext());
webView.destroy();
webView = null;
}
}
After struggling for many days, finally I figured out the root cause of your problem. It is probably because of the heavy javascript code that webview needs to parse. Try to lighten it a bit and you are all set, the numeric keypad won't get invisible.
How can I click on a link that is provided in the WebView data that I load?
The WebView data that is load is in HTML format as:
<P CLASS="western" ALIGN=JUSTIFY STYLE="margin-bottom: 0.14in">Further
here</P>
The WebView is placed inside a scroll view and its webClient is as:
webViewClient = new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
#Override
public void onLoadResource(WebView view, String url)
{
}
};
webView = (WebView) findViewById(R.id.tos); // Defining the WebView for the terms and conditions and loading the required data
webView.setWebViewClient(webViewClient);
webView.loadData(getResources().getString(R.string.terms_of_service), "text/html", "UTF-8");
The problem is that when I click on the Link no action takes place. How can this be resolved?
use this code to open
WebView webView;//make sure to initialize
webView.setWebViewClient(webViewClient);
WebViewClient webViewClient= new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
return true;
}
#Override
public void onLoadResource(WebView view, String url){
if( url.equals("http://yoururl.com") ){
// do something
}
}
}
I'm trying to use a facebook login button that uses JS Facebook SDK on Android Webview. When I click it open a new page and redirects to https://www.facebook.com/dialog/oauth... which is a blank page with a javascript code. And the webview stays here.
I'm using:
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setAppCacheEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
Thank you!
You need to add logic to redirect back to the original url of your website.
In order to do this, you need to first create a new java class that extends the WebViewClient class and overrides the onPageFinished method like this:
public class CustomWebViewClient extends WebViewClient
{
#Override
public void onPageFinished(WebView view, String url) {
//https://www.facebook.com/dialog/permissions.request
//actually works for me, but I put the URL you say is coming up
//blank in there instead, whatever works for you:
if(url.startsWith("https://www.facebook.com/dialog/oauth")){
String redirectUrl = "http://www.mydomain.com/MyApp/";
view.loadUrl(redirectUrl);
return;
}
super.onPageFinished(view, url);
}
}
Second, just add it to your WebView:
webview.setWebViewClient(new CustomWebViewClient());
Once that page is finished loading, it will redirect back to your original page
I dont know what exactly i did at that time, but the problem was solved. I'll give you the code. Try finding out :)
WebView browser,mWebviewPop;
private void open(){
browser = (WebView)findViewById(R.id.webView1);
browser.getSettings().setLoadsImagesAutomatically(true);
browser.getSettings().setJavaScriptEnabled(true);
browser.getSettings().setAppCacheEnabled(true);
browser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
browser.getSettings().setSupportMultipleWindows(true);
browser.setWebViewClient(new MyBrowser());
browser.setWebChromeClient(new MyCustomChromeClient());
mContext=this.getApplicationContext();
browser.loadUrl(target_url);
MainActivity.this.progressBar.setProgress(0);
browser.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
}
private class MyBrowser extends WebViewClient {
String redirectUrl = "MY URL";
private void noInternet() {
WebView webview = (WebView) findViewById(R.id.webView1);
RelativeLayout tryAgainLayout = (RelativeLayout)findViewById(R.id.tryAgainLayout);
RelativeLayout progressLayout = (RelativeLayout)findViewById(R.id.progressLayout);
tryAgainLayout.setVisibility(View.VISIBLE);
webview.setVisibility(View.GONE);
webview.destroy();
progressLayout.setVisibility(View.INVISIBLE);
}
public void visible(){
WebView webview = (WebView) findViewById(R.id.webView1);
RelativeLayout tryAgainLayout = (RelativeLayout)findViewById(R.id.tryAgainLayout);
RelativeLayout progressLayout = (RelativeLayout)findViewById(R.id.progressLayout);
tryAgainLayout.setVisibility(View.INVISIBLE);
webview.setVisibility(View.INVISIBLE);
progressLayout.setVisibility(View.VISIBLE);
}
public void unvisible(){
WebView webview = (WebView) findViewById(R.id.webView1);
RelativeLayout tryAgainLayout = (RelativeLayout)findViewById(R.id.tryAgainLayout);
RelativeLayout progressLayout = (RelativeLayout)findViewById(R.id.progressLayout);
tryAgainLayout.setVisibility(View.INVISIBLE);
webview.setVisibility(View.VISIBLE);
progressLayout.setVisibility(View.INVISIBLE);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String host = Uri.parse(url).getHost();
if (host.equals(target_url_prefix))
{
if(mWebviewPop!=null)
{
mWebviewPop.setVisibility(View.GONE);
baseLayout.removeView(mWebviewPop);
mWebviewPop=null;
}
return false;
}
if(host.equals("m.facebook.com"))
{
return false;
}
view.loadUrl(url);
return true;
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
noInternet();
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
visible();
}
#Override
public void onPageFinished(WebView view, String url) {
unvisible();
System.out.println("\n" +view.getUrl());
if(url.startsWith("https://m.facebook.com/v2.1/dialog/oauth")){
if(mWebviewPop!=null)
{
mWebviewPop.setVisibility(View.GONE);
baseLayout.removeView(mWebviewPop);
mWebviewPop=null;
}
view.loadUrl(redirectUrl);
return;
}
super.onPageFinished(view, url);
}
}
private class MyCustomChromeClient extends WebChromeClient
{
#Override
public boolean onCreateWindow(WebView view, boolean isDialog,
boolean isUserGesture, Message resultMsg) {
mWebviewPop = new WebView(mContext);
mWebviewPop.setVerticalScrollBarEnabled(false);
mWebviewPop.setHorizontalScrollBarEnabled(false);
mWebviewPop.setWebViewClient(new MyBrowser());
mWebviewPop.getSettings().setJavaScriptEnabled(true);
mWebviewPop.getSettings().setSavePassword(false);
mWebviewPop.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
baseLayout.addView(mWebviewPop);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(mWebviewPop);
resultMsg.sendToTarget();
return true;
}
#Override
public void onCloseWindow(WebView window) {
}
#Override
public void onProgressChanged(WebView view, int newProgress) {
MainActivity.this.setValue(newProgress);
super.onProgressChanged(view, newProgress);
}
}
OK so from what I can tell, what's happening here is that there are two "ways" for oauth to work, either it will call back "to aparent page" (like popup "log me in" that disappears), or it can redirect you to a login page, then to some other url (non popup style), after success or failure (kind of a chain forward). Unfortunately it appears WebView is not well suited for the "callback to the parent page" style, so you have to do some shenanigans like have a second WebView (jincy's answer here, or see also this).
How I get the web page's source from WebView?
I want to only enter www.google.com in my webview and When I entered this site, I want to get the source for example
String a=........;(source)
I am not sure how far this is going to be helpful. But I have used the below snippet to fetch a small html page's data. I hope it helps you.
Create a class like the one below,
class MyJavaScriptInterface
{
#SuppressWarnings("unused")
public void processHTML(final String html)
{
Log.i("processed html",html);
Thread OauthFetcher=new Thread(new Runnable() {
#Override
public void run() {
String oAuthDetails=null;
oAuthDetails=Html.fromHtml(html).toString();
Log.i("oAuthDetails",oAuthDetails);
}
});OauthFetcher.start();
}
}
Now in your onCreate(),
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
webview.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, final String url) {
String oAuthUrl=getString("www.google.com");
if(url.contains(oAuthUrl))
{
Log.i("Contains","Auth URL");
twitter_webview.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
}
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
progressDialog.show();
}
});
And now what happens is that, when your page finishes loading, the JavaScript class will be called, which would retrieve the page source and store it in a String as your requirement.
And For API 17
import android.webkit.JavascriptInterface;
public class MainActivity extends Activity {
final Context myApp = this;
#JavascriptInterface
public void processHTML(String html) {
if (html == null)
return;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WebView browser = (WebView) findViewById(R.id.webview);
browser.getSettings().setJavaScriptEnabled(true);
browser.addJavascriptInterface(this, "HTMLOUT");
browser.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
browser.loadUrl("javascript:window.HTMLOUT.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
}
});
browser.loadUrl("http://www.google.co.il");
}
}
If your minSdkVersion is 19 or greater you can use the following.
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.evaluateJavascript("""(function() {
return "<html>" + document.getElementsByTagName('html')[0].innerHTML + "</html>";
})()""".trimMargin()) {
console.log(it)
}
}