Android - как перехватить форму POST в android WebViewClient на уровне API 4
У меня есть WebViewClient
, прикрепленный к моему WebView
, например:
webView.setWebViewClient(new MyWebViewClient());
Вот моя реализация MyWebViewClient
:
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webView.loadUrl(url);
return true;
}
}
Я даю WebView
URL для загрузки через loadUrl()
. Если у меня есть ссылка (a href...
) на странице, мой метод shouldOverrideUrlLoading
вызывается, и я могу перехватить ссылку.
Однако, если у меня есть форма, метод которой POST
, метод shouldOverrideUrlLoading
не вызывается.
Я заметил аналогичную проблему: http://code.google.com/p/android/issues/detail?id=9122, которая, как представляется, предполагает переопределение postUrl
в моем WebView
. Однако этот API доступен только начиная с уровня API 5.
Что мне делать, если я на уровне API 4? Есть ли другой способ перехватить сообщения формы?
Ответы
Ответ 1
Это известная проблема, что shouldOverrideUrlLoading
не улавливает POST. Подробнее см. http://code.google.com/p/android/issues/detail?id=9122.
Используйте GET! Я лично пытался использовать POST, потому что ожидал некоторого ограничения параметров GET (т.е. Длины URL), но я просто успешно передал 32000 байт через GET локально без каких-либо проблем.
Ответ 2
Вам действительно нужно использовать POST? Если вы хотите обрабатывать formdata локально, почему бы вам не обработать часть javascript вашей формы и интерфейса с "родным" Java-кодом с помощью addJavascriptInterface. Например.
WebView engine = (WebView) findViewById(R.id.web_engine);
engine.getSettings().setJavaScriptEnabled(true);
engine.addJavascriptInterface(new MyBridge(this), "bridge");
engine.loadUrl(...)
Ваш мост может быть любым классом в основном, и вы должны иметь доступ к его методам непосредственно из javascript. Например.
public class MyBridge {
public MyBridge(Context context) {
// ...
}
public String doIt(String a, String b) {
JSONArray result = new JSONArray();
result.put("Hello " + a);
result.put("Hello " + b);
return result.toString();
}
Ваш html/javascript может выглядеть так:
<script type="text/javascript">
$("#button").click(function() {
var a = $("#a").val();
var b = $("#b").val();
var result=JSON.parse(bridge.doIt(a, b));
// ...
}
</script>
<input id="a"><input id="b"><button id="button">click</button>
Ответ 3
Я думаю, вы можете переопределить onLoadResource(WebView view, String url)
от WebViewClient
. Эта функция добавлена в API LEVEL 1.
Эта функция вызывается, когда WebView
будет загружать ресурс, указанный данным URL. Ресурс включает js
, css
, iframe
вложенный URL. Пример кода:
@Override
public void onLoadResource(WebView view, String url) {
if (url.indexOf("http://www.example.com") != -1 && view != null) {
// open url in default browser
view.stopLoading();
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
}