如何从webview获取html内容?
哪一个从webview获取html代码最简单的方法? 我已经尝试了几种方法从stackoverflow和谷歌,但无法find一个确切的方法。 请提一个确切的方法。
public class htmldecoder extends Activity implements OnClickListener,TextWatcher { TextView txturl; Button btgo; WebView wvbrowser; TextView txtcode; ImageButton btcode; LinearLayout llayout; int flagbtcode; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.htmldecoder); txturl=(TextView)findViewById(R.id.txturl); btgo=(Button)findViewById(R.id.btgo); btgo.setOnClickListener(this); wvbrowser=(WebView)findViewById(R.id.wvbrowser); wvbrowser.setWebViewClient(new HelloWebViewClient()); wvbrowser.getSettings().setJavaScriptEnabled(true); wvbrowser.getSettings().setPluginsEnabled(true); wvbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); wvbrowser.addJavascriptInterface(new MyJavaScriptInterface(),"HTMLOUT"); //wvbrowser.loadUrl("http://www.google.com"); wvbrowser.loadUrl("javascript:window.HTMLOUT.showHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');"); txtcode=(TextView)findViewById(R.id.txtcode); txtcode.addTextChangedListener(this); btcode=(ImageButton)findViewById(R.id.btcode); btcode.setOnClickListener(this); } public void onClick(View v) { if(btgo==v) { String url=txturl.getText().toString(); if(!txturl.getText().toString().contains("http://")) { url="http://"+url; } wvbrowser.loadUrl(url); //wvbrowser.loadData("<html><head></head><body><div style='width:100px;height:100px;border:1px red solid;'></div></body></html>","text/html","utf-8"); } else if(btcode==v) { ViewGroup.LayoutParams params1=wvbrowser.getLayoutParams(); ViewGroup.LayoutParams params2=txtcode.getLayoutParams(); if(flagbtcode==1) { params1.height=200; params2.height=220; flagbtcode=0; //txtcode.setText(wvbrowser.getContentDescription()); } else { params1.height=420; params2.height=0; flagbtcode=1; } wvbrowser.setLayoutParams(params1); txtcode.setLayoutParams(params2); } } public class HelloWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } /*@Override public void onPageFinished(WebView view, String url) { // This call inject JavaScript into the page which just finished loading. wvbrowser.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');"); }*/ } class MyJavaScriptInterface { @SuppressWarnings("unused") public void showHTML(String html) { txtcode.setText(html); } } public void afterTextChanged(Editable s) { // TODO Auto-generated method stub } public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } public void onTextChanged(CharSequence s, int start, int before, int count) { wvbrowser.loadData("<html><div"+txtcode.getText().toString()+"></div></html>","text/html","utf-8"); } }
其实这个问题有很多答案。 这里有两个:
- 第一个和你的差不多,我想我们是从同一个教程中得到的。
public class TestActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webview); final WebView webview = (WebView) findViewById(R.id.browser); webview.getSettings().setJavaScriptEnabled(true); webview.addJavascriptInterface(new MyJavaScriptInterface(this), "HtmlViewer"); webview.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { webview.loadUrl("javascript:window.HtmlViewer.showHTML" + "('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');"); } }); webview.loadUrl("http://android-in-action.com/index.php?post/" + "Common-errors-and-bugs-and-how-to-solve-avoid-them"); } class MyJavaScriptInterface { private Context ctx; MyJavaScriptInterface(Context ctx) { this.ctx = ctx; } public void showHTML(String html) { new AlertDialog.Builder(ctx).setTitle("HTML").setMessage(html) .setPositiveButton(android.R.string.ok, null).setCancelable(false).create().show(); } } }
这样你通过javascript获取html。 不是最漂亮的方法,但是当你有你的JavaScript接口时,你可以添加其他方法来修补它。
- 另一种方法是使用像这样的HttpClient。
你select的选项也取决于,我想,你打算如何处理检索到的HTML …
对于android 4.2,不要忘了添加@JavascriptInterface到所有的javasscript函数
在KitKat及以上版本中,您可以在webview上使用evaluateJavascript
方法
wvbrowser.evaluateJavascript( "(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();", new ValueCallback<String>() { @Override public void onReceiveValue(String html) { Log.d("HTML", html); // code here } });
看到这个答案更多的例子
Android WebView只是另一个呈现引擎,可以呈现从HTTP服务器下载的HTML内容,非常像Chrome或FireFox。 我不知道你为什么需要从WebView获取呈现的页面(或截图)的原因。 对于大多数情况,这是没有必要的。 您始终可以直接从HTTP服务器获取原始HTML内容。
已经有关于使用HttpUrlConnection或HttpClient获取原始stream的答案。 另外,在处理Android上的HTML内容分析/处理时,有一个非常方便的库: JSoup ,它提供了非常简单的API来从HTTP服务器获取HTML内容,并提供HTML文档的抽象表示,以帮助我们不仅pipe理HTMLparsing在更OO的风格,但也很容易:
// Single line of statement to get HTML document from HTTP server. Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
例如,当您想要首先下载HTML文档,然后添加一些自定义CSS或JavaScript,然后将其传递到WebView进行呈现之前,它非常方便。 更多在他们的官方网站上,值得去检查一下。
我发现一个接触点需要在Proguardconfiguration中隐藏起来。 虽然HTML阅读器在debugging应用程序时通过javascript接口调用就可以,但是应用程序通过Proguard运行后不再工作,除非在Proguardconfiguration文件中声明了HTML阅读器函数,如下所示:
-keepclassmembers class <your.fully.qualified.HTML.reader.classname.here> { public *; }
在Android 2.3.6,4.1.1和4.2.1上testing并确认。
Android不会让你这样做的安全问题。 一个邪恶的开发者很容易窃取用户input的login信息。
相反,在显示之前,您必须捕捉显示在webview中的文本。 如果你不想build立一个响应处理程序(根据其他答案),我发现这个修复与一些谷歌search:
URL url = new URL("https://stackoverflow.com/questions/1381617"); URLConnection con = url.openConnection(); Pattern p = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*"); Matcher m = p.matcher(con.getContentType()); /* If Content-Type doesn't match this pre-conception, choose default and * hope for the best. */ String charset = m.matches() ? m.group(1) : "ISO-8859-1"; Reader r = new InputStreamReader(con.getInputStream(), charset); StringBuilder buf = new StringBuilder(); while (true) { int ch = r.read(); if (ch < 0) break; buf.append((char) ch); } String str = buf.toString();
这是很多代码,你应该能够复制/贴上它,在它的结尾str
将包含在web视图中绘制相同的HTML。 这个答案是从最简单的方法来正确加载网页中的HTML到Java中的string ,它也应该在Android上工作。 我没有testing过,也没有自己写,但它可能会帮助你。
而且,这个拉的URL是硬编码的,所以你必须改变它。
为什么不先获取html然后传递给web视图?
private String getHtml(String url){ HttpGet pageGet = new HttpGet(url); ResponseHandler<String> handler = new ResponseHandler<String>() { public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { HttpEntity entity = response.getEntity(); String html; if (entity != null) { html = EntityUtils.toString(entity); return html; } else { return null; } } }; pageHTML = null; try { while (pageHTML==null){ pageHTML = client.execute(pageGet, handler); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return pageHTML; } @Override public void customizeWebView(final ServiceCommunicableActivity activity, final WebView webview, final SearchResult mRom) { mRom.setFileSize(getFileSize(mRom.getURLSuffix())); webview.getSettings().setJavaScriptEnabled(true); WebViewClient anchorWebViewClient = new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); //Do what you want to with the html String html = getHTML(url); if( html!=null && !url.equals(lastLoadedURL)){ lastLoadedURL = url; webview.loadDataWithBaseURL(url, html, null, "utf-8", url); } }
这应该大致做你想做的事情。 它是适应从是否有可能从WebView的HTML代码,并呼吁https://stackoverflow.com/users/325081/aymon-fournier的答案。;
我build议不要试图从WebView中提取HTML,而是从URL中提取HTML。 通过这个,我的意思是使用JSoup等第三方库来遍历HTML。 以下代码将从您的特定url获取HTML
public static String getHtml(String url) throws ClientProtocolException, IOException { HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet, localContext); String result = ""; BufferedReader reader = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) ); String line = null; while ((line = reader.readLine()) != null){ result += line + "\n"; } return result; }
尝试使用HttpClient作为Sephy说:
public String getHtml(String url) { HttpClient vClient = new DefaultHttpClient(); HttpGet vGet = new HttpGet(url); String response = ""; try { ResponseHandler<String> vHandler = new BasicResponseHandler(); response = vClient.execute(vGet, vHandler); } catch (Exception e) { e.printStackTrace(); } return response; }
它的简单实现只需要在您的HTML javasript方法来获得html内容的价值。 如上所示,您的代码需要进行一些更改。
public class htmldecoder extends Activity implements OnClickListener,TextWatcher { Button btsubmit; // this button in your xml file WebView wvbrowser; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.htmldecoder); btsubmit=(Button)findViewById(R.id.btsubmit); btsubmit.setOnClickListener(this); wvbrowser=(WebView)findViewById(R.id.wvbrowser); wvbrowser.setWebViewClient(new HelloWebViewClient()); wvbrowser.getSettings().setJavaScriptEnabled(true); wvbrowser.getSettings().setPluginsEnabled(true); wvbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); MyJavaScriptInterface myinterface=new MyJavaScriptInterface(); wvbrowser.addJavascriptInterface(myinterface,"interface"); webView.loadUrl("file:///android_asset/simple.html"); //use one html file for //testing put your html file in assets. Make sure that you done JavaScript methods to get //values for html content in html file . } public void onClick(View v) { if(btsubmit==v) { webView.loadUrl("javascript:showalert()");// call javascript method. //wvbr } } final class MyJavaScriptInterface { MyJavaScriptInterface() { } public void sendValueFromHtml(String value) { System.out.println("Here is the value from html::"+value); } } }
你的Javascript在html中
<script type="text/javascript"> //<![CDATA[ var n1; function callme(){ n1=document.getElementById("FacadeAL").value; } function showalert(){ window.interface.sendValueFromHtml(n1);// this method calling the method of interface which //you attached to html file in android. // & we called this showalert javasript method on //submmit buttton click of android. } //]]> </script>
&确保你在html中调用下面的callme
<input name="FacadeAL" id="FacadeAL" type="text" size="5" onblur="callme()"/>
希望这会帮助你。
我build议尝试一下Reflection方法,如果你有时间花在debugging器上(对不起,但我没有)。
从android.webkit.WebView
类的loadUrl()
方法开始:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/webkit/WebView.java#WebView.loadUrl%28java.lang.String %2Cjava.util.Map 29%
您应该到达调用nativeLoadUrl()
本机方法的android.webkit.BrowserFrame
:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/webkit/BrowserFrame.java#BrowserFrame.nativeLoadUrl%28java.lang.String %2Cjava.util.Map 29%
本地方法的实现应该在这里:
祝你好运!
上面给出的方法是如果你有一个url,但如果你有一个本地的HTML,那么你也可以有这个代码的HTML
AssetManager mgr = mContext.getAssets(); try { InputStream in = null; if(condition)//you have a local html saved in assets { in = mgr.open(mFileName,AssetManager.ACCESS_BUFFER); } else if(condition)//you have an url { URL feedURL = new URL(sURL); in = feedURL.openConnection().getInputStream();} // here you will get your html String sHTML = streamToString(in); in.close(); //display this html in the browser or web view } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } public static String streamToString(InputStream in) throws IOException { if(in == null) { return ""; } Writer writer = new StringWriter(); char[] buffer = new char[1024]; try { Reader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); int n; while ((n = reader.read(buffer)) != -1) { writer.write(buffer, 0, n); } } finally { } return writer.toString(); }