GeoLocation in WebView

jvckejvcke Member ✭✭

I have created a web-application that uses the Google Maps JavaScript API.
The application works fine in a regular browser, even on mobile phones.

I am now trying to "wrap" the web-app in a Xamarin WebView, so that I can deploy it as a mobile app.
I'm focusing on trying to get it to work on Android first, then deal with iPhone later.
Therefore, it doesn't really matter if I get this to work with Xamarin.Forms or Xamarin.Android. As long as it works, I'm happy.

The problem is that when my javascript calls the navigator.geolocation.getCurrentPosition
When this happens in a regular browser, you get prompted with a question that asks if you allow the app to get your current position. You presss "allow" and the app continues.

This doesn't happen when the the app wrapped in a WebView.

I've created a simple webpage that uses the navigator.geolocation.getCurrentPosition method and just displays lat & lng inside a h1 tag on the page.

Here is the page: httpsjakethesnake .se

If I'm able to get that page to work in a WebView, hopefully my real app with google maps will work too.

I've read a couple of stackoverflow threads and other posts about this. Most of the solutions there are obsolete or works sometimes and sometimes not.

Thankful for any help.

Tagged:

Answers

  • JohnHardmanJohnHardman GBUniversity mod

    @jvcke

    Have you specified the appropriate permissions in the Android manifest in the Android-specific project of your Xamarin.Forms app?

    I'd start with:
    ACCESS_COARSE_LOCATION
    ACCESS_FINE_LOCATION
    LOCATION_HARDWARE

    As an aside - if you are basically building a thin wrapper around a web view in order to create a native app, have you considered using Apache Cordova instead of Xamarin.Forms?

  • jvckejvcke Member ✭✭

    @JohnHardman Thank you for answering.

    I think the manifest is OK:

      <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.LOCATION_HARDWARE" />
    

    My app is working when I manually go in to my app settings and enable location pemissions for the app. Although it's a 5 second delay for the javascript callback to return to the app with the coordinates...but that's better than nothing.

    I want my code to trigger an alert that gives the user the ability to accept the permissions.
    I guess you cant force permissions nowadays?

    This is my code so far (Mainactivity):

    public class MainActivity : AppCompatActivity
    {
        WebView webView;
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.activity_main);
            webView = FindViewById<WebView>(Resource.Id.webView1);
    
            webView.SetWebViewClient(new GeoWebViewClient());
            webView.SetWebChromeClient(new GeoWebChromeClient());
    
            webView.Settings.JavaScriptCanOpenWindowsAutomatically = true;
            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.DomStorageEnabled = true;
            webView.Settings.SetGeolocationEnabled(true);
    
            webView.LoadUrl("httpswww.jakethesnake.se/");
        }
    }
    
    public class GeoWebChromeClient : WebChromeClient
    {
        public override  void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)
        {
            callback.Invoke(origin, true, false);
        }
    }
    
    public class GeoWebViewClient : WebViewClient
    {
        public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
        {
            Android.Net.Uri url = request.Url;
            view.LoadUrl(url.ToString());
            return true;
        }
        public override void OnReceivedSslError(WebView view, SslErrorHandler handler, SslError er)
        {
            // Ignore SSL certificate errors
            handler.Proceed();
        }
    }
    
  • jvckejvcke Member ✭✭

    I've also tried this. This actually prompts the user and asks for permissions.
    It seems that my javascript doesn't wait for this though. And even if the user presses "allow", nothing really happens in the appsettings.

       public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)
                {
                    const bool remember = false;
                    var builder = new Android.App.AlertDialog.Builder(_context);
    
                    builder.SetTitle("Location")
                            .SetMessage(string.Format("{0} would like to use your current location", origin))
                            .SetPositiveButton("Allow", (sender, args) => callback.Invoke(origin, true, remember))
                            .SetNegativeButton("Disallow", (sender, args) => callback.Invoke(origin, false, remember));
    
                    var alert = builder.Create();
                    alert.Show();
                }
    
Sign In or Register to comment.