使用 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;
}
我在 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;
}