使用webView时是否可以将HTML表单中的数据导入android?

时间:2016-11-30 13:05:06

标签: javascript android webview html-parsing code-injection

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

我想在按钮点击的android中的变量中输入名为“thebox”的输入框中的值,之前我尝试过很多东西,然后我按照一个方法来注入一个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,所以我无法理解并且继承了我在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");
    }

我在MainActivity中创建的嵌套类:

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中的webview中显示的html表单(输入框)中获取价值,是否真的可以这样做,如果是,请解释一下?谢谢,也请告诉我将获得什么变量值。

7 个答案:

答案 0 :(得分:18)

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

添加此接口类,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的设置并调用setJavaScriptEnabled(true);为真。

2)要创建Javascript代码和Android代码之间的接口,需要创建Javacript接口类。

3)将你的javascript代码之间的接口绑定到android代码,你需要传递接口类的引用和你的javaScript可以调用的接口名来访问该类。

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

5)创建如下所示的接口类(WebAppInterface)。

请参阅此链接了解更多详情     https://developer.android.com/guide/webapps/webview.html

HTML文件中的

6),创建按钮并将点击监听器添加到该按钮,并使用接口名称(此处为Android)调用sendData(“您的值”)函数。

多数民众赞成。你可以将值从html传递给你的android代码。

答案 1 :(得分:2)

对于使用方法“GET”的表单,只需覆盖shouldOverrideUrlLoading方法就可以实现这一点。仅当通过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);
    }
}

答案 2 :(得分:2)

与原生android通信webView, 这是一个简单的方法: 在你的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;

});

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

您可以通过捕获警报消息从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());

答案 5 :(得分:1)

@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 side context。

第2步:

这是您的HTML端代码(webview)。 如果您在webview中访问的URL是您的,那么您可以轻松地将这些代码写入html页面,但如果您正在访问某些第三方URL,您仍可以通过以下代码行将此js代码注入webview:

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

那么这里到底发生了什么:

&#39; X&#39;是js中保存所需值的变量,然后我们发送这个&#39; x&#39;通过方法调用 Android.processHTML(x)

将变量转换为android上下文

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

答案 6 :(得分:0)

到目前为止最好的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;
}