使用 webView 时是否可以从 HTML 表单中获取数据到 android 中?

Is it possible to get data from HTML forms into android while using webView?

我在 HTML 中制作了一个非常简单的表单,在 android 中使用 webview 查看它,它使用文本框输入你的名字,当你点击按钮时,它会显示出来进入一个段落,它是使用 html 和 javascript 制作的。 这是我的 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>

新编辑的表格

<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>

我想在单击按钮时从名为 "thebox" 的变量中的 android 中的变量中获取值,我之前尝试了很多东西,我遵循了一种注入JS 文件,但由于我对 JS 一无所知,所以我尝试失败了,这是我放入项目中的文件,文件名为 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;
};

后来,当我关注那篇文章时,它说我需要在我的 MainActivity 中添加一些东西,但由于我是第一次使用 webview,所以我不太了解,这是我添加到我的代码中的代码主要活动:

 @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");
    }

我在 MainActivity 中创建的嵌套 class:

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

最后是注入代码的方法:

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();
    }

我想从我在 Android 的网络视图中显示的 html 表单(输入框)中获取价值,是否真的可以这样做,如果可以,如何以及请解释?谢谢,也请告诉我将在哪个变量中获得值。

可以,您可以使用java脚本获取网页内容。然后使用webview jsInterface return内容给你java代码。

参考这个github project. and this answer and this 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");

希望对您有所帮助。

您可以通过捕获警报消息从 WebView 获取数据。

使用 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());
    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");

添加此接口class、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;
 }
}

你的HTML代码数据

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

在android webview中点击html按钮时调用此函数

更新

1) 默认情况下 javascript 在 webview 中被禁用。要启用它,请获取 webview 的设置并调用 setJavaScriptEnabled(true);为真。

2) 要在 Javascript 代码和 android 代码之间创建接口,您需要创建 Javacript 接口 class。

3)绑定你的javascript代码到android代码的接口,你需要传递接口class的引用以及您的 javaScript 可以调用以访问 class.

的接口名称

4) 传递 html 文件路径以加载到 webview(浏览器)中。

5) 创建接口 class 如下所示 (WebAppInterface).

查看此 link 了解更多详情 https://developer.android.com/guide/webapps/webview.html

6) 在 HTML 文件中,创建按钮并将点击侦听器添加到该按钮,并调用带有接口的 sendData("your value") 函数名称(此处 Android)。

就是这样。您可以将值从 html 传递给您的 android 代码。

对于具有方法 "GET" 的表单,您只需重写 shouldOverrideUrlLoading 方法即可非常简单地实现这一点。以下解决方案仅在通过 webview.loadUrl() 方法加载 url 时有效。

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);
    }
}

将 webView 与本机通信 android, 这是一个简单的方法: 在你的 js onClick 按钮上,你应该调用 url 包含你的文本,比如 myPrefix://myData 在 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;

});

是的,这是可能的。请尝试使用以下代码

@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();
    }
}

@Shariq 许多人已经很好地回答了这个问题,但我认为你还需要澄清数据是如何从 webview 流入代码到 andorid 的,所以我不会浪费字节来写所有冗余代码:

(我正在参考您的代码以便更好地理解) 按照这些代码中的这些步骤进行操作以更好地理解:

第 1 步:

我们需要在 Android 端定义一些方法,可以从 webview

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

现在它的值将可用于 java android 侧上下文。

第 2 步:

这是您的 HTML 辅助代码(网络视图)。 如果您在 webview 中访问的 URL 是您自己的,那么您可以轻松地将这些代码写入 html 页面,但是如果您正在访问第三方 URL 您仍然可以将此 js 代码注入 webview只需通过以下代码行:

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

那么这里究竟发生了什么:

'x' 是 js 中保存所需值的变量,然后我们通过方法调用 [=36= 将此 'x' 变量发送到 android 上下文](x)

我希望它能以更好的方式帮助你

迄今为止使用的最好的注入 js,它在提交时从所有表单收集数据

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;
}