Android WebView: Calling C# from JavaScript

Laut Dokumentation soll es möglich sein, in einem Android WebView von JavaScript aus auf Java-Funktionen zuzugreifen. Entsprechend sollte dies auch mit C# und Xamarin möglich sein. Viel Nachforschen und Ausprobieren – leider war kein Online-Beispiel wirklich funktionsfähig – führten mich schließlich zu folgender Lösung (für API Level 19):

var webView = FindViewById(Resource.Id.webView);
webView.Settings.JavaScriptEnabled = true;

var webChromeClient = new MyWebChromeClient();
webView.SetWebChromeClient(webChromeClient);

var webViewClient = new MyWebViewClient();
webView.SetWebViewClient(webViewClient);

webView.AddJavascriptInterface(webViewClient, "apiCalls");
webView.LoadUrl(...);

Dabei scheint hier vor allem der eigene WebChromeClient wichtig zu sein. Das eigentliche Interface implementiert die veröffentlichten Methoden „public“ und mit „Export“ und „JavascriptInterace“ getaggt wie folgt:

[Export("setNextCallDetails")]
[JavascriptInterface]
public void SetNextCallDetails(string method, string jsonData)
{
	...
}

In JavaScript wird dies dann so aufgerufen:

<script src="js/vendor/jquery-2.1.3.min.js"></script>
<script>
	$(document).ajaxSend(function (event, jqXHR, ajaxOptions) {
		if (apiCalls) {
			if (apiCalls.setNextCallDetails) {
				var method = ajaxOptions.type;
				var jsonData = (typeof ajaxOptions.data === "string"
				? ajaxOptions.data
				: ajaxOptions.data
				? JSON.stringify(ajaxOptions.data)
				: null);

				apiCalls.setNextCallDetails(method, jsonData);
			}
		}
	});
</script>

Wozu das Ganze?

Ganz einfach: der WebView unterstützt (auf API Level 19) keine Übermittlung der HTTP-Methode und des POST/PUT-Bodys an den registrierten WebViewClient. Mit obiger Methode kann ich AJAX-Aufrufe abfangen, die nötigen Informationen vorab setzen und dann den WebViewClient seine Arbeit tun lassen.

Schreibe einen Kommentar