title: Monotouch / Mono for Android Javascript to C#
body: <p>I am prototyping a HTML5 app using the Xamarin framework.  I am trying to connect javascript to C# code and vice versa.</p>
  
  <p>What is the best way to do this?  So far I have tried creating Mono C# bindings to the Cordova framework, which is not an ideal solution and am looking for something more straightforward that takes advantage of a common .Net centric approach.  So I have tried setting up a HttpListener to handle app http requests from javacript calls.  This method works well with Monotouch, but doesn't with Mono for Android</p>
  
  <p>Javascript call:</p>
  
  <pre><code>&lt;script type="text/javascript"&gt;
      function myFunction()
      {
          var request = new XMLHttpRequest();
          request.open('GET','http://127.0.0.1:8001/callnative', false);
          request.send();
  
          if(request.status == 200){
              alert("Callback!");
          }
          else{
              alert("Error");
          }
      }
  &lt;/script&gt;
  </code></pre>
  
  <p>Here is the C# code in the Activity class:</p>
  
  <pre><code>[Activity (Label = "AnroidHTML5Prototype", MainLauncher = true)]
      public class Activity1 : Activity
      {
          int count = 1;
  
          public HttpListener listener;
  
          protected override void OnCreate (Bundle bundle)
          {
              base.OnCreate (bundle);
  
              SetupListener ();
  
              // Set our view from the "main" layout resource
              SetContentView (Resource.Layout.Main);
  
              // Get our button from the layout resource,
              // and attach an event to it
              Button button = FindViewById&lt;Button&gt; (Resource.Id.myButton);
  
              button.Click += delegate {
                  button.Text = string.Format ("{0} clicks!", count++);
              };
  
              LoadWebView ();
          }
  
          private void LoadWebView()
          {
              string lfn = "index.html";
              string html = string.Empty;
  
              // context could be ApplicationContext, Activity or
              // any other object of type Context
              using (var input = this.ApplicationContext.Assets.Open(lfn))
                  using (StreamReader sr = new System.IO.StreamReader(input))
              {
                  html = sr.ReadToEnd();
              }
  
              WebView webView = FindViewById&lt;WebView&gt; (Resource.Id.webView1);
              webView.SetWebChromeClient(new WebChromeClient());
              webView.Settings.JavaScriptEnabled = true;
              webView.LoadData (html, "text/html", null);
              webView.Settings.AllowFileAccess = true;
              webView.Settings.BlockNetworkLoads = false;
          }
  
          private void SetupListener() {
              listener = new HttpListener();
              listener.Prefixes.Add("http://*:8001/");
              listener.Start();
  
              listener.BeginGetContext(new AsyncCallback(HandleRequest), listener);
          }
  
          public void HandleRequest (IAsyncResult result)
          {
              RunOnUiThread(delegate{
  
                  //Get the listener context
                  HttpListenerContext context = listener.EndGetContext(result);
  
                  //Start listening for the next request
                  listener.BeginGetContext(new AsyncCallback(HandleRequest), listener);
  
                  string response = String.Empty;
  
                  if (context.Request.Url.ToString ().Contains ("callnative")) {
                      response = "native code reply";
                  }
  
                  byte[] responseBytes = System.Text.Encoding.UTF8.GetBytes(response);
  
                  context.Response.ContentType = "text/json";
                  context.Response.StatusCode = (int)HttpStatusCode.OK;
                  context.Response.ContentLength64 = responseBytes.Length;
                  context.Response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
                  context.Response.OutputStream.Close();
  
  
  //          WebView webView = FindViewById&lt;WebView&gt; (Resource.Id.webView1);
  //          webView.LoadUrl("javascript:(function() { " +  
  //                          "alert('Callback!'); " +  
  //                          "})()"); 
  
              });
          }
      }
  </code></pre>
  
  <p>Similar code works fine in Monotouch, but in Mono for Android, I get the following errors:
  [Web Console] XMLHttpRequest cannot load http:// 127.0.0.1:8001/callnative. Cannot make any requests from null.:1
  [Web Console] Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101:1</p>
  
  <p>Which I think has to do with Chrome Browser file permissions, so I set the AllowFileAccess setting on the WebView to true, but still get the same error.  </p>
  
  <p>Is there a better way to accomplish a bridge between javascript and C# in Mono, or a way to get the HTTPListener code to work with Android?  </p>
  
  <p>This article comes up in the Xamarin documentation search, but is a 404:</p>
  
  <p><a href="http://docs.xamarin.com/recipes/android/controls/webview/call_c#_from_javascript" rel="nofollow">http://docs.xamarin.com/recipes/android/controls/webview/call_c#_from_javascript</a></p>
  
  <p>Thanks
  Derrick</p>