web-dev-qa-db-fra.com

android - extraire du texte de la vue Web

Dans mon application, je montre des fichiers HTML epub dans webview en utilisant EPUBLIB . Mon problème est que je souhaite utiliser la fonctionnalité de signet pour mon lecteur epub. Pour cela, je veux récupérer le texte de webview qui affiche une page du fichier HTML de mon epub, puis utiliser ce texte dans mon activité de signet pour montrer à l'utilisateur ce qu'il a mis en favori . Comment puis-je y parvenir?

20
Rohit

Obtenir le contenu en texte brut à partir d'une vue Web est plutôt difficile. En gros, les classes Android ne l'offrent pas, mais javascript le fait, et Android offre à javascript un moyen de transmettre les informations à votre code. 

Avant d’entrer dans les détails, notez que si votre structure html est simple, il serait peut-être préférable que vous utilisiez pour analyser simplement les données manuellement.

Ceci dit, voici ce que vous faites:

  1. Activer javascript
  2. Ajoutez votre propre classe d'interface javascript , pour permettre au javascript de communiquer avec votre code Android 
  3. Enregistrez votre propre webviewClient , en remplaçant le onPageFinished pour insérer un peu de javascript
  4. Dans le javascript, procurez-vous le element.innerText de la balise et transmettez-le à votre interface javascript.

Pour clarifier, je posterai un exemple de code de travail (mais très approximatif) ci-dessous. Il affiche une vue Web en haut et une vue texte avec le contenu textuel en bas.

package test.Android.webview;

import Android.app.Activity;
import Android.os.Bundle;
import Android.webkit.WebView;
import Android.webkit.WebViewClient;
import Android.widget.TextView;

public class WebviewTest2Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WebView webView = (WebView) findViewById(R.id.webView);
        TextView contentView = (TextView) findViewById(R.id.contentView);

        /* An instance of this class will be registered as a JavaScript interface */ 
        class MyJavaScriptInterface 
        { 
            private TextView contentView;

            public MyJavaScriptInterface(TextView aContentView)
            {
                contentView = aContentView;
            }

            @SuppressWarnings("unused") 

            public void processContent(String aContent) 
            { 
                final String content = aContent;
                contentView.post(new Runnable() 
                {    
                    public void run() 
                    {          
                        contentView.setText(content);        
                    }     
                });
            } 
        } 

        webView.getSettings().setJavaScriptEnabled(true); 
        webView.addJavascriptInterface(new MyJavaScriptInterface(contentView), "INTERFACE"); 
        webView.setWebViewClient(new WebViewClient() { 
            @Override 
            public void onPageFinished(WebView view, String url) 
            { 
                view.loadUrl("javascript:window.INTERFACE.processContent(document.getElementsByTagName('body')[0].innerText);"); 
            } 
        }); 

        webView.loadUrl("http://shinyhammer.blogspot.com");
    }
}

En utilisant le fichier main.xml suivant:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical" >

    <WebView
        Android:id="@+id/webView"
        Android:layout_width="match_parent"
        Android:layout_height="fill_parent"
        Android:layout_weight="0.5" />

    <TextView
        Android:id="@+id/contentView"
        Android:layout_width="match_parent"
        Android:layout_height="fill_parent"
        Android:layout_weight="0.5" />


</LinearLayout>
38
Paul-Jan
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
        }
});
5
Balaji M

Dans ce cas, la seule chose qui me vienne à l'esprit est d'utiliser du javascript. En faisant une recherche rapide, j'ai trouvé Android.webkit.WebView.addJavascriptInterface .

Vous voulez étudier le "addJavascriptInterface" qui à la fin vous aidera à résoudre le problème

4
Th0rndike

La solution fournie ci-dessus fournit le texte à l'aide de la propriété innerText qui vous renverra tout le texte de la vue Web. La solution que je propose ci-dessous vous aidera à extraire le texte de la partie visible de la WebView à l'écran.

Étape 1: Il nécessite l’aide de javaScript. Par conséquent, activez d’abord le javascript.

webView.addJavascriptInterface(new IJavascriptHandler(getActivity().getApplicationContext()),     "Android"); //if your class extends a Fragment class

ou

view.addJavascriptInterface(new IJavascriptHandler(this), "Android"); //if your class extends Activity.

Étape 2: Créez une classe interne javaInterface.

final class IJavascriptHandler {

    Context mContext;
    IJavascriptHandler(Context c) {
    mContext = c;
}

//API 17 and higher required you to add @JavascriptInterface as mandatory before your method.   
@JavascriptInterface 
public void processContent(String aContent) 
{ 
   //this method will be called from within the javascript method that you will write.
   final String content = aContent;
   Log.e("The content of the current page is ",content);
} 
}

Étape 3: Maintenant, vous devez ajouter la méthode javascript. Vous allez écrire la méthode sous forme de chaîne puis la charger. La méthode retourne le texte en fonction du paramètre fourni. Donc, vous auriez besoin de 2 chaînes. L'un chargera la méthode javascript et l'autre l'appellera.

Méthode pour charger la méthode javascript.

String javaScriptToExtractText = "function getAllTextInColumn(left,top,width,height){"
                +   "if(document.caretRangeFromPoint){"
                +   "var caretRangeStart = document.caretRangeFromPoint(left, top);"
                +   "var caretRangeEnd = document.caretRangeFromPoint(left+width-1, top+height-1);"
                +   "} else {"
                +   "return null;"
                +   "}"
                +   "if(caretRangeStart == null || caretRangeEnd == null) return null;"
                +   "var range = document.createRange();"
                +   "range.setStart(caretRangeStart.startContainer, caretRangeStart.startOffset);"
                +   "range.setEnd(caretRangeEnd.endContainer, caretRangeEnd.endOffset);"
                +   "return range.toString();};";

Méthode pour appeler la fonction ci-dessus.

String javaScriptFunctionCall = "getAllTextInColumn(0,0,100,100)";

//I've provided the parameter here as 0,0 i.e the left and top offset and then 100, 100 as width and height. So, it'll extract the text present in that area.

Étape 4: Maintenant, vous devez charger les 2 javascripts ci-dessus.

webView.loadURL("javascript:"+ javaScriptToExtractText);
//this will load the method.


view.loadUrl("javascript:window.Android.processContent("+javaScriptFunctionCall+");");
//this will call the loaded javascript method.

Prendre plaisir.

2
Arunavh Krishnan

Pourquoi ne récupérez-vous pas directement le texte avec EPUBLIB dans le livre?

Vous avez ce html avec l'aide d'EPUBLIB, n'est-ce pas? Comment avez-vous mis cela dans le webvieuw? Je ne vois aucun exemple.

0
Helper