comment obtenir du contenu HTML à partir d’une webview?

Quelle est la méthode la plus simple pour obtenir du code HTML depuis une vue Web? J’ai essayé plusieurs méthodes de stackoverflow et google, mais je ne trouve pas de méthode exacte. S’il vous plaît mentionner une manière exacte.

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(''+document.getElementsByTagName('html')[0].innerHTML+'');"); 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) { Ssortingng url=txturl.getText().toSsortingng(); if(!txturl.getText().toSsortingng().contains("http://")) { url="http://"+url; } wvbrowser.loadUrl(url); //wvbrowser.loadData("
","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, Ssortingng url) { view.loadUrl(url); return true; } /*@Override public void onPageFinished(WebView view, Ssortingng url) { // This call inject JavaScript into the page which just finished loading. wvbrowser.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');"); }*/ } class MyJavaScriptInterface { @SuppressWarnings("unused") public void showHTML(Ssortingng 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("
","text/html","utf-8"); } }

En fait, cette question a beaucoup de réponses. Voici 2 d’entre eux:

  • Ce premier est presque le même que le vôtre, je suppose que nous l’avons obtenu à partir du même tutoriel.

 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, Ssortingng url) { webview.loadUrl("javascript:window.HtmlViewer.showHTML" + "(''+document.getElementsByTagName('html')[0].innerHTML+'');"); } }); 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(Ssortingng html) { new AlertDialog.Builder(ctx).setTitle("HTML").setMessage(html) .setPositiveButton(android.R.ssortingng.ok, null).setCancelable(false).create().show(); } } } 

De cette façon, vous récupérez le HTML via javascript. Pas la plus belle façon, mais lorsque vous avez votre interface javascript, vous pouvez append d’autres méthodes pour la bricoler.


  • Un autre moyen consiste à utiliser un HttpClient comme ici .

Je pense que l’option que vous choisissez dépend de ce que vous avez l’intention de faire avec le fichier HTML récupéré …

Pour Android 4.2, n’oubliez pas d’append @JavascriptInterface à toutes les fonctions javasscript

Dans KitKat et au-dessus, vous pouvez utiliser la méthode assessmentJavascript sur webview

 wvbrowser.evaluateJavascript( "(function() { return (''+document.getElementsByTagName('html')[0].innerHTML+''); })();", new ValueCallback() { @Override public void onReceiveValue(Ssortingng html) { Log.d("HTML", html); // code here } }); 

Voir cette réponse pour plus d’exemples

Android WebView est juste un autre moteur de rendu qui rend le contenu HTML téléchargé depuis un serveur HTTP, tout comme Chrome ou FireFox. Je ne connais pas la raison pour laquelle vous devez obtenir la page rendue (ou la capture d’écran) de WebView. Pour la plupart des situations, cela n’est pas nécessaire. Vous pouvez toujours obtenir directement le contenu HTML brut à partir du serveur HTTP.

Il existe déjà des réponses concernant l’obtention du stream brut en utilisant HttpUrlConnection ou HttpClient. Alternativement, il existe une bibliothèque très pratique pour traiter l’parsing / le traitement du contenu HTML sur Android: JSoup , il fournit une API très simple pour obtenir le contenu HTML du serveur HTTP et fournit une représentation abstraite du document HTML pour nous aider à gérer l’parsing HTML non seulement dans un style plus OO mais aussi beaucoup plus facile:

 // Single line of statement to get HTML document from HTTP server. Document doc = Jsoup.connect("http://en.wikipedia.org/").get(); 

C’est pratique lorsque, par exemple, vous souhaitez télécharger un document HTML, puis y append un script CSS ou javascript personnalisé avant de le transmettre à WebView pour le rendre. Beaucoup plus sur leur site Web officiel, cela vaut la peine de le vérifier.

Un sharepoint contact que j’ai trouvé qui doit être mis en place est “masqué” dans la configuration Proguard. Bien que le lecteur HTML appelle à travers l’interface javascript lors du débogage de l’application, cela ne fonctionne plus dès que l’application est exécutée via Proguard, à moins que la fonction lecteur HTML ne soit déclarée dans le fichier de configuration Proguard, comme ceci:

 -keepclassmembers class  { public *; } 

Testé et confirmé sur Android 2.3.6, 4.1.1 et 4.2.1.

Android ne vous laissera pas faire cela pour des raisons de sécurité. Un développeur maléfique pourrait très facilement voler des informations de connexion saisies par l’utilisateur.

Au lieu de cela, vous devez intercepter le texte affiché dans la vue Web avant son affichage. Si vous ne voulez pas configurer un gestionnaire de réponse (comme pour les autres réponses), j’ai trouvé ce correctif avec du googling:

 URL url = new URL("https://stackoverflow.com/questions/1381617"); URLConnection con = url.openConnection(); Pattern p = Pattern.comstack("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. */ Ssortingng charset = m.matches() ? m.group(1) : "ISO-8859-1"; Reader r = new InputStreamReader(con.getInputStream(), charset); SsortingngBuilder buf = new SsortingngBuilder(); while (true) { int ch = r.read(); if (ch < 0) break; buf.append((char) ch); } String str = buf.toString(); 

C'est beaucoup de code, et vous devriez pouvoir le copier / coller, et à la fin de celui-ci, str contiendra le même fichier HTML dessiné dans la vue Web. Cette réponse est du moyen le plus simple pour charger correctement le HTML de la page Web dans une chaîne de caractères en Java et cela devrait également fonctionner sur Android. Je ne l'ai pas testé et je ne l'ai pas écrit moi-même, mais cela pourrait vous aider.

De plus, l'URL que vous extrayez est codée en dur, vous devrez donc changer cela.

Pourquoi ne pas obtenir le HTML d’abord, puis le passer à la vue Web?

 private Ssortingng getHtml(Ssortingng url){ HttpGet pageGet = new HttpGet(url); ResponseHandler handler = new ResponseHandler() { public Ssortingng handleResponse(HttpResponse response) throws ClientProtocolException, IOException { HttpEntity entity = response.getEntity(); Ssortingng html; if (entity != null) { html = EntityUtils.toSsortingng(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, Ssortingng url, Bitmap favicon) { super.onPageStarted(view, url, favicon); //Do what you want to with the html Ssortingng html = getHTML(url); if( html!=null && !url.equals(lastLoadedURL)){ lastLoadedURL = url; webview.loadDataWithBaseURL(url, html, null, "utf-8", url); } } 

Cela devrait faire à peu près ce que vous voulez faire. Est-il possible d’obtenir le code HTML de WebView et de crier à https://stackoverflow.com/users/325081/aymon-fournier pour sa réponse.

Je suggérerais plutôt que d’essayer d’extraire le HTML de WebView, vous extrayez le HTML de l’URL. Par cela, je veux dire utiliser une bibliothèque tierce telle que JSoup pour parcourir le HTML pour vous. Le code suivant récupérera le code HTML d’une URL spécifique pour vous

 public static Ssortingng getHtml(Ssortingng url) throws ClientProtocolException, IOException { HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet, localContext); Ssortingng result = ""; BufferedReader reader = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) ); Ssortingng line = null; while ((line = reader.readLine()) != null){ result += line + "\n"; } return result; } 

essayez d’utiliser HttpClient comme Sephy a dit:

 public Ssortingng getHtml(Ssortingng url) { HttpClient vClient = new DefaultHttpClient(); HttpGet vGet = new HttpGet(url); Ssortingng response = ""; try { ResponseHandler vHandler = new BasicResponseHandler(); response = vClient.execute(vGet, vHandler); } catch (Exception e) { e.printStackTrace(); } return response; } 

Son simple à mettre en œuvre Il suffit de disposer de méthodes javasript dans votre fichier HTML pour obtenir la valeur du contenu HTML. Comme ci-dessus votre code, certaines modifications sont nécessaires.

  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(Ssortingng value) { System.out.println("Here is the value from html::"+value); } } } 

Votre Javascript en HTML

   

& Assurez-vous d’appeler callme comme ci-dessous en html


J’espère que ceci vous aidera.

Je suggère d’essayer une approche Reflection, si vous avez le temps de passer sur le débogueur (désolé mais je n’en avais pas).

À partir de la méthode loadUrl() de la classe android.webkit.WebView :

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.Ssortingng % 2Cjava.util.Map% 29

Vous devriez arriver sur android.webkit.BrowserFrame qui appelle la méthode native nativeLoadUrl() :

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.Ssortingng % 2Cjava.util.Map% 29

L’implémentation de la méthode native devrait être ici:

http://gitorious.org/0xdroid/external_webkit/blobs/a538f34148bb04aa6ccfbb89dfd5fd784a4208b1/WebKit/android/jni/WebCoreFrameBridge.cpp

Je vous souhaite bonne chance!

les méthodes ci-dessus sont pour si vous avez une URL Web, mais si vous avez un HTML local, vous pouvez aussi avoir HTML par ce code

 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 Ssortingng sHTML = streamToSsortingng(in); in.close(); //display this html in the browser or web view } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } public static Ssortingng streamToSsortingng(InputStream in) throws IOException { if(in == null) { return ""; } Writer writer = new SsortingngWriter(); 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.toSsortingng(); }