Geolocation in WebView - Droid

AshySlashy87 6 Reputation points
2021-02-26T19:26:05.75+00:00

Hi Guys,

I have problems getting the location data via a WebView...

Getting the location data via Geolocation.GetLastKnownLocationAsync(); works perfectly.
Permissions is requested in runtime.

Hope someone can Help =)

Thanks in advance!

Same Data:

Minimum Android-Version: API26
Target-Version: API26

Manifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<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" />

MainPage.xaml

<?xml version="1.0" encoding="utf-8"?> 
<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:GeoLocTest" 
    x:Class="GeoLocTest.MainPage"> 
    <StackLayout> 
        <local:GeoWebView Source="https://example.domain.com" x:Name="myWebView" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"></local:GeoWebView> 
        <Button Text="get location" Clicked="Button_ClickedAsync"/> 
        <Label x:Name="myLocation"/> 
    </StackLayout> 
</ContentPage> 

MainPage.xaml.cs

namespace GeoLocTest 
{ 
    public partial class MainPage : ContentPage 
    { 
        public MainPage() 
        { 
            InitializeComponent(); 
        } 

        private async void Button_ClickedAsync(System.Object sender, System.EventArgs e) 
        { 
            var location = await Geolocation.GetLastKnownLocationAsync(); 

            myLocation.Text = $"Latitude: {location.Latitude}, Longitude: {location.Longitude} {DateTime.Now.Ticks} "; 
        } 
    } 
} 

MainActivity.cs

namespace GeoLocTest.Droid 
{ 
    [Activity(Label = "GeoLocTest", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 
    { 
        protected override void OnCreate(Bundle savedInstanceState) 
        { 
            TabLayoutResource = Resource.Layout.Tabbar; 
            ToolbarResource = Resource.Layout.Toolbar; 

            base.OnCreate(savedInstanceState); 

            Xamarin.Essentials.Platform.Init(this, savedInstanceState); 
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState); 

            LoadApplication(new App()); 
        } 
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) 
        { 
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); 

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults); 
        } 


        protected override void OnStart() 
        { 
            base.OnStart(); 
            if (CheckSelfPermission(Manifest.Permission.AccessCoarseLocation) != (int)Permission.Granted) 
            { 
                RequestPermissions(new string[] { Manifest.Permission.AccessCoarseLocation, Manifest.Permission.AccessFineLocation }, 0); 
            } 


        } 
    } 
} 

GeoWebView.cs

namespace GeoLocTest 
{ 
    public class GeoWebView : WebView 
    { 
    } 

} 

GeoWebViewRenderer.cs

[assembly: ExportRenderer(typeof(GeoWebView), typeof(GeoWebViewRenderer))] 
namespace GeoLocTest.Droid 
{ 
    public class GeoWebViewRenderer : WebViewRenderer 
    { 

        public GeoWebViewRenderer(Context context) : base(context) 
        { 
        } 

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) 
        { 
            base.OnElementChanged(e); 
            Control.Settings.JavaScriptEnabled = true; 
            Control.Settings.AllowFileAccess = true; 
            Control.Settings.SetGeolocationEnabled(true); 
            Control.Settings.SetGeolocationDatabasePath(Control.Context.FilesDir.Path); 

        } 
    }

} 
Developer technologies | .NET | Xamarin

1 answer

Sort by: Most helpful
  1. AshySlashy87 6 Reputation points
    2021-05-28T21:48:07.667+00:00

    @J Brooks

    GeoWebViewRenderer.cs

    using System;   
        using Android.App;   
        using Android.Content;   
        using Android.Provider;   
        using Android.Webkit;   
        using AndroidX.Core.Content;   
        using Java.IO;   
        using Xamarin.Forms;   
        using Xamarin.Forms.Platform.Android;   
           
        [assembly: ExportRenderer(typeof(GeoLocTest.GeoWebView), typeof(GeoLocTest.Droid.GeoWebViewRenderer))]   
        
           
        namespace GeoLocTest.Droid   
        {   
            public class GeoWebViewRenderer : WebViewRenderer   
            {   
                public GeoWebViewRenderer(Context context) : base(context)   
                {   
                }   
       
                protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)   
                {   
                    base.OnElementChanged(e);   
                    Control.Settings.JavaScriptEnabled = true;   
                    Control.Settings.AllowFileAccess = true;   
                    Control.Settings.AllowFileAccessFromFileURLs = true;   
                    Control.Settings.AllowContentAccess = true;   
                    Control.Settings.BlockNetworkImage = false;   
                    Control.Settings.AllowUniversalAccessFromFileURLs = true;   
                    Control.Settings.DomStorageEnabled = true;   
                    Control.Settings.SetAppCacheEnabled(false);   
                    Control.Settings.DatabaseEnabled = true;   
                    Control.Settings.DomStorageEnabled = true;   
                    MyWebClient cwc = new MyWebClient(MainActivity.Instance);   
                    Control.SetWebChromeClient(cwc);   
           
                    Control.Settings.SetGeolocationEnabled(true);   
                    Control.Settings.SetGeolocationDatabasePath(Control.Context.FilesDir.Path);   
           
                    Control.LoadUrl("https://www.google.com/");   
                }   
            }   
    
            public class MyWebClient : WebChromeClient   
            {   
                Activity mActivity = null;   
                public MyWebClient(Activity activity)   
                {   
                    mActivity = activity;   
                }   
    
                public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)   
                {   
                    callback.Invoke(origin, true, true);   
                }   
            }   
        }   
    

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.