Search code examples
androidxamarinxamarin.android

Issue with WebView.EvaluateJavaScript in Android Xamarin


I am using the following code for injecting Java Script in to my Android Web view

WebView

webView = FindViewById<WebView> (Resource.Id.learningWebView);
if (null != webView) {
    webView.Settings.JavaScriptEnabled = true;
    webView.Settings.SetSupportZoom (true);
    webView.SetWebViewClient (new CustomWebViewClient ());

 }

WebView Client implementation

public class CustomWebViewClient : WebViewClient
{
    public override bool ShouldOverrideUrlLoading (WebView view, string url)
    {
        view.LoadUrl (url);
        return true;
    }

    public override void OnPageStarted (WebView view, string url, Android.Graphics.Bitmap favicon)
    {

    }

    public override void OnPageFinished (WebView view, string url)
    {
        base.OnPageFinished (view, url);
        HideLearningDivs (view);
    }


    void HideLearningDivs (WebView view)
    {
        try {

            view.EvaluateJavascript ("document.getElementById(\"suiteBar\").parentNode.style.display='none'", new JavaScriptResult ());
        } catch (Exception ex) {
            Console.WriteLine (ex.Message);
        }

    }

IValueCallback Implementation

public class JavaScriptResult :  IValueCallback
{
    public IntPtr Handle {
        get;
        set;
    }

    public void Dispose ()
    {

    }



    public void OnReceiveValue (Java.Lang.Object result)
    {

    }
}

But during the time of executing the application I am getting the following error.

java.lang.NoSuchMethodError: no method with name='evaluateJavascript' signature='(Ljava/lang/String;Landroid/webkit/ValueCallback;)V' in class Landroid/webkit/WebView;

Can anyone please help me to find what is wrong with my implementation.


Solution

  • I will link to where I found the answer below, but basically you need to do a check for Android KitKat (4.4), since that function was not introduced until then. If the device is running lower than 4.4, then you may need to do something different to get the value back if you actually need to do something with it. Such as using a Hybrid WebView of some kind (check out Xamarin Forms Labs version of it perhaps) and/or using the AddJavaScriptInterface()

    Here is the code:

    if(Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat) {
        webView.EvaluateJavascript("javascript:GoBack();", null);
    } else {
        webView.LoadUrl("javascript:GoBack();");
    }
    

    https://forums.xamarin.com/discussion/24894/webview-evaluatejavascript-issues

    *Edit: Since writing this, I found an excellent post Adam Pedley (who I apparently have been linking to a lot lately) which covers doing this for Xamarin Forms but also mentions a change in Android 4.2 to the JS engine. Running the JavaScript might work the first time but it also sets the document object to the script result, so you may need to assign the result of document.getElementById() to a variable in order to work around this: var x = document.getElementById().