Question

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:

Call C# from JavaScript

Monodroid Javascript Call-back

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top