I want to call a C# class/method from within the HTML loaded in my WebView
.
I have defined a class JS2CS
which contains a single method to show a Toast
, as follows:
using Android.Content;
using Android.Widget;
using Java.Interop;
namespace CrossPlatformApp_Android
{
public class JS2CS : Java.Lang.Object
{
private Context context;
public JS2CS (Context context)
{
this.context = context;
}
[Export ("run")]
public void Run ()
{
Toast.MakeText (context, "Hello from C#", ToastLength.Short).Show ();
}
}
}
I have defined a button in my HomePage.html
file as follows:
<button type="button" onclick="JS2CS.run()" >Call C#</button>
HomePage.html
is saved in the Assets
folder of my project and I load it into my WebView
as follows:
myWebView.Settings.JavaScriptEnabled = true;
myWebView.SetWebChromeClient (new CustomWebChromeClient());
myWebView.LoadUrl ("file:///android_asset/Content/HomePage.html");
CustomWebChromeClient
is a simple extension of WebChromeClient
which offers no additional functionality over its parent.
Lastly, I inject my JS2CS
object into my WebView
after calling LoadUrl(...)
, as follows:
myWebView.AddJavascriptInterface (new JS2CS (this), "JS2CS");
Unfortunately this does not do the job. When I launch my application and click the html button, I get the following message:
[Web Console] Uncaught ReferenceError: JS2CS is not defined at file:///android_asset/Content/HomePage.html:22
If I call the AddJavascriptInterface(...)
method before LoadUrl(...)
instead, I get the following error message:
[Web Console] Uncaught TypeError: Object [object Object] has no method 'run' at file:///android_asset/Content/HomePage.html:22
Any ideas anybody??!!
The above implementation is based on the following two urls:
Hmm, after trying all kinds of things... I stumbled across this sentence in the Android WebView.addJavascriptInterface(Object, String) documentation:
...For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript...
And I lowered my Android Application's Target Version from API 19 to API 14 and made no other changes to the code in the question and it now works! Hurrah! That does now pose the question however of how to inject a JavaScript interface into a WebView
for app's targeting API 17+ but that's another question for another thread...
Edit: To get it to work for an app targeting API 17+, all you have to do is add the
[JavascriptInterface]
annotation to the method being exported.