web-dev-qa-db-fra.com

Est-il possible de récupérer les données des formulaires HTML dans Android lors de l'utilisation de webView?

Je fais un formulaire très simple en HTML qui est affiché en Android en utilisant la vue Web qui prend votre nom en utilisant une zone de texte et lorsque vous cliquez sur le bouton, il l'affiche dans un paragraphe et il est fait en utilisant à la fois html et javascript. Voici mon code html:

<!DOCTYPE html>
<html>
<body>
<p> Write your name and win your favorite game console name and win it! The winners will be announced in 4 days.</p>
Type your name here: <input id="thebox" type="text" name="value" value=""><br>

    <button onclick="myFunction()">Try it</button>

    <p id="demo"></p>

    <script>
    function myFunction() {
        var x = document.getElementById("thebox").value;
        document.getElementById("demo").innerHTML = x;
    }
    </script>

    </body>
    </html>

NOUVEAU FORMULAIRE MODIFIÉ

<form name="albert" action="" method="POST">

 <label for="firstname"> First Name </label>
 <br /><br />

 <input type="text" name="firstname" id="firstname" />

 <input type="submit" name="sbumit" value="Submit" />


</form>

Je veux obtenir la valeur de la zone de saisie appelée "thebox" dans une variable en Android sur le bouton cliquer et j'ai essayé beaucoup de choses avant et j'ai suivi une méthode où vous injectez un fichier JS mais comme je ne connais rien à JS, j'ai échoué et voici le fichier que j'ai mis dans mon projet et le fichier s'appelle inject.js:

document.getElementsByTagName('form')[0].onsubmit = function () {
    var objPWD, objAccount, objSave;
    var str = '';
    var inputs = document.getElementsByTagName('thebox');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].name.toLowerCase() === 'thebox') {
            objAccount = inputs[i];
        }
    }
    if(objAccount != null) {
        str += objAccount.value;
    }
    if(objPWD != null) {
        str += ' , ' + objPWD.value;
    }
    if(objSave != null) {
        str += ' , ' + objSave.value;
    }
    window.AndroidInterface.processHTML(str);
    return true;
};

Et plus tard, alors que je suivais cet article, il était dit que je devais mettre des choses dans mon MainActivity mais comme j'utilise Webview pour la première fois, je ne comprenais pas grand-chose et voici le code que j'ai mis dans mon MainActivity:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WebView webView = new WebView(this);
        this.setContentView(webView);

        // enable javascript
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new JavaScriptInterface(), "AndroidInterface");

        // catch events
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                try {
                    view.loadUrl("javascript:" + buildInjection());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

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

Une classe imbriquée que j'ai créée dans mon MainActivity:

class JavaScriptInterface {
        @JavascriptInterface
        public void processHTML(String formData) {
            Log.d("AWESOME_TAG", "form data: " + formData);
        }
    }

Et enfin la méthode qui injecte le code:

private String buildInjection() throws IOException {
        StringBuilder buf = new StringBuilder();
        InputStream inject = getAssets().open("inject.js");// file from assets
        BufferedReader in = new BufferedReader(new InputStreamReader(inject, "UTF-8"));
        String str;
        while ((str = in.readLine()) != null) {
            buf.append(str);
        }
        in.close();

        return buf.toString();
    }

Je veux obtenir de la valeur du formulaire html (the-input-box) que je montre dans une vue Web en Android et est-il vraiment possible de le faire et si oui comment et s'il vous plaît expliquer? Merci et veuillez également indiquer dans quelle variable vais-je obtenir la valeur.

19
Shariq Musharaf
    Webview browser=(WebView)view.findViewById(R.id.webChart);
    browser.getSettings().setJavaScriptEnabled(true);
    browser.addJavascriptInterface(new WebAppInterface(getActivity()), "Android");
    browser.loadUrl("file:///Android_asset/yourHtmlFileName.html");

ajoutez cette classe d'interface, WebAppInterface

public class WebAppInterface {
 Context mContext;
 String data;

 WebAppInterface(Context ctx){
    this.mContext=ctx;
 } 


 @JavascriptInterface
 public void sendData(String data) {
    //Get the string value to process
      this.data=data;
 }
}

vos données de code HTML

 function loadChartData() {
  var x = document.getElementById("thebox").value;
   Android.sendData(x);
 }

appeler cette fonction lorsque le bouton html clique dans Android webview

[~ # ~] mise à jour [~ # ~]

1) Par défaut, javascript est désactivé dans la vue Web. pour l'activer, obtenez les paramètres de la vue Web et appelez setJavaScriptEnabled (true); à vrai.

2) pour créer l'interface entre votre code Javascript et votre Android, vous devez créer une classe d'interface Javacript.

3) liez l'interface entre votre code javascript à Android code, vous devez passer la référence de la classe d'interface et un nom d'interface que votre javaScript peut appeler pour accéder à la classe.

4) passez le chemin du fichier html à charger dans la vue Web (navigateur).

5) créez la classe d'interface comme ci-dessous (WebAppInterface).

voir ce lien pour plus de détails https://developer.Android.com/guide/webapps/webview.html

6) dans le fichier HTML, créez le bouton et ajoutez l'écouteur de clics à ce bouton et appelez la fonction sendData ("votre valeur") avec le nom de l'interface ( Ici Android).

C'est tout. vous pouvez transmettre la valeur de html à votre Android.

20
Noorul

Oui, vous pouvez utiliser le javascript pour obtenir le contenu de la page Web. Utilisez ensuite la vue Web jsInterface pour vous renvoyer le contenu Java code.

Reportez-vous à projet github . et ceci réponse et ceci article .

final Context myApp = this;

/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface
{
    @JavascriptInterface
    @SuppressWarnings("unused")
    public void processHTML(String html)
    {
        // process the html as needed by the app
    }
}

final WebView browser = (WebView)findViewById(R.id.browser);
/* JavaScript must be enabled if you want it to work, obviously */
browser.getSettings().setJavaScriptEnabled(true);

/* Register a new JavaScript interface called HTMLOUT */
browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");

/* WebViewClient must be set BEFORE calling loadUrl! */
browser.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url)
    {
        /* This call inject JavaScript into the page which just finished loading. */
        browser.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
    }
});

/* load a web page */
browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html");

J'espère que cela t'aides.

5
Kris Roofe

Pour les formulaires avec la méthode "GET", vous pouvez réaliser cela assez simplement en remplaçant la méthode shouldOverrideUrlLoading. La solution suivante ne fonctionne que si l'url a été chargée via la méthode webview.loadUrl().

private class MWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) { 
        // submit will end-up with url like "data:,?firstname=SomeInput&sbumit=Submit"
        if (URLUtil.isDataUrl(url)) {
            url = url.replace(":,?", ":/?"); //to be able to properly parse Uri
            Uri uri = Uri.parse(url);

            //here you can get params by field name 
            String firstname = uri.getQueryParameter("firstname");

            //we handle this URL ourselves 
            return true;
        }

        return super.shouldOverrideUrlLoading(view, url);
    }
}
3
j2ko

Pour communiquer une webView avec Android natif, c'est un moyen simple: dans votre js onClick sur le bouton, vous devez appeler l'URL qui contient votre texte, quelque chose comme myPrefix: // myData et dans Android

webView.setWebViewClient(new WebViewClient()
{
   @Override
   public boolean shouldOverrideUrlLoading(final WebView view, final String url) 
    {
     if(url.startsWith("myPrefix://")) 
      {
       //get your data by split url
       return true;
      }
 return false;

});
2
Ahmed.ess

@Shariq Comme beaucoup ont déjà répondu à cette question dans le bon sens, mais je pense en outre que vous avez besoin d'éclaircissements sur la façon dont les données circulent dans les codes de la vue Web vers andorid, donc je ne gaspillerai pas d'octets par écrit que tous les codes redondants:

(Je prends référence à vos codes pour une meilleure compréhension) Suivez ces étapes dans ces codes pour mieux comprendre:

Étape 1:

Nous devons définir une méthode du côté Android côté qui peut accepter certaines données de la vue Web

@JavascriptInterface
//this 'formData' variable is going to accept the data from webview 
public void processHTML(String formData) {
    Log.d("AWESOME_TAG", "form data: " + formData);
}

Maintenant, sa valeur sera disponible pour Java Android contexte latéral.

Étape 2:

voici vos codes HTML (webview). si l'URL à laquelle vous accédez dans la vue Web est la vôtre, vous pouvez facilement écrire ces codes sur la page HTML, mais si vous accédez à une URL tierce, vous pouvez toujours injecter ce code js dans la vue Web simplement en suivant la ligne de code:

...
//partial code
webView.load("javascript:function myFunction() { var x = document.getElementById('thebox').value; Android.processHTML(x); } myFunction();";
... 

Alors, que se passe-t-il exactement ici:

'x' est la variable en js contenant la valeur requise, puis nous envoyons cette variable 'x' à Android via l'appel de méthode Android.processHTML (x)

J'espère que cela pourrait vous aider d'une meilleure façon

Oui c'est possible. Veuillez essayer d'utiliser le code ci-dessous

>  @Override
>     public void onCreate(Bundle savedInstanceState) {
>         super.onCreate(savedInstanceState);
>         setContentView(R.layout.web_view_layout);
>         WebView webView = (WebView) findViewById(R.id.webView);
>         webView.getSettings().setPluginState(WebSettings.PluginState.ON);
>         WebSettings webSettings = webView.getSettings();
>         webSettings.setJavaScriptEnabled(true);
>         try {
>             progressDialog = new ProgressDialog(ActivityName);
>         progressDialog.setMessage("Loading.."); progressDialog.setCancelable(false);
>             webView.setWebViewClient(new MyWebViewClient());
>             webView.loadUrl(YOUR_URL);
>         } catch (Exception e) {
>             e.toString();
>         }
>     }
> 
>     private class MyWebViewClient extends WebViewClient {
> 
>         @Override
>         public boolean shouldOverrideUrlLoading(WebView view, String url) {
>             view.loadUrl(url);
>            progressDialog.dismissProgress();
>             return true;
>         }
> 
>         @Override
>         public void onPageFinished(WebView view, String url) {
>             progressDialog.dismissProgress();
>         }
>     }
2
Deepali-Systematix

Vous pouvez obtenir des données de WebView en interceptant des messages d'alerte.

Utilisez WebChromeClient.

mWebview = (WebView)findViewById(R.id.yourwebviewlayout);
final class YourWebChromeClient extends WebChromeClient {
                @Override
                public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                    Toast.makeText(getApplicationContext(),
                            "alert message =  " + message,
                            Toast.LENGTH_SHORT).show();
                    result.confirm();
                    return true;
                }
            }
mWebview.setWebChromeClient(new YourWebChromeClient());
1
Rainmaker

Les meilleurs js à injecter ont utilisé jusqu'à présent, il recueille des données de tous les formulaires sur soumettre

document.getElementsByTagName("form")[0].addEventListener("submit", myFunction);
function myFunction()
{
    var data="";
    var inputs = document.forms[0].getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        var field = inputs[i];
        if (field.type != 'submit' && field.type != 'reset' && field.type != 'button')
        data += '' + field.name + '=' + field.value+'\n';
    }
    window.AndroidInterface.processHTML(data);
    return true;
}
0
Sikini Joseph