Ответ 1
Как указано в моем собственном комментарии к исходному вопросу, работает подход JavaScript-инъекции. В основном, что вам нужно сделать, это добавить часть кода JavaScript в событие DOM onsubmit, проанализировать поля формы и вернуть результат обратно к зарегистрированной Java функции.
Пример кода:
public class MyBrowser extends Activity {
private final String jsInjectCode =
"function parseForm(event) {" +
" var form = this;" +
" // make sure form points to the surrounding form object if a custom button was used" +
" if (this.tagName.toLowerCase() != 'form')" +
" form = this.form;" +
" var data = '';" +
" if (!form.method) form.method = 'get';" +
" data += 'method=' + form.method;" +
" data += '&action=' + form.action;" +
" 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;" +
" }" +
" HTMLOUT.processFormData(data);" +
"}" +
"" +
"for (var form_idx = 0; form_idx < document.forms.length; ++form_idx)" +
" document.forms[form_idx].addEventListener('submit', parseForm, false);" +
"var inputs = document.getElementsByTagName('input');" +
"for (var i = 0; i < inputs.length; i++) {" +
" if (inputs[i].getAttribute('type') == 'button')" +
" inputs[i].addEventListener('click', parseForm, false);" +
"}" +
"";
class JavaScriptInterface {
@JavascriptInterface
public void processFormData(String formData) {
//added annotation for API > 17 to make it work
<do whatever you need to do with the form data>
}
}
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browser);
WebView browser = (WebView)findViewById(R.id.browser_window);
browser.getSettings().setJavaScriptEnabled(true);
browser.addJavascriptInterface(new JavaScriptInterface(), "HTMLOUT");
browser.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:(function() { " +
MyBrowser.jsInjectCode + "})()");
}
}
Неформально, это означает, что пользовательский код JavaScript (как обработчик onsubmit
) вводит каждый раз, когда страница заканчивает загрузку. При представлении формы Javascript будет анализировать данные формы и передавать ее обратно на Землю Java через объект JavaScriptInterface
.
Чтобы разобрать поля формы, код Javascript добавляет обработчики формы onsubmit
и onclick
. Первый может обрабатывать представления канонической формы через обычную кнопку отправки, в то время как последний имеет дело с пользовательскими кнопками отправки, то есть с кнопками, которые делают некоторую дополнительную магию JavaScript перед вызовом form.submit()
.
Имейте в виду, что код Javascript может быть не идеальным: могут быть другие методы отправки формы, которую мой код не может быть уловлен. Тем не менее, я убежден, что введенный код можно обновить, чтобы справиться с такими возможностями.