【问题标题】:Xamarin Forms WebView Geolocation issueXamarin Forms WebView 地理位置问题
【发布时间】:2017-07-07 08:31:12
【问题描述】:

我正在尝试在 xamarin 表单应用程序中启用 webview 以获取 android 设备的当前 GPS 坐标。目前,当在手机或笔记本电脑上的 chrome 浏览器中打开时,webview/网站将返回 GPS 坐标,但在应用程序中不会。试图让这个工作尽可能简单,并在之后对其进行扩展。

到目前为止的代码: 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"
             x:Class="UITrial.Page2"
             BackgroundColor = "#f0f0ea">
    <Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />

  <WebView Source="https://danu6.it.nuigalway.ie/OliverInternetProgramming/project/Loginproject.html" />

</ContentPage>

HTML 页面:

<!DOCTYPE html>
<html>
<body>

<p>Click the button to get your coordinates.</p>

<button onclick="getLocation()">Try It</button>

<p id="demo"></p>

<script>
var x = document.getElementById("demo");

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.watchPosition(showPosition);
    } else { 
        x.innerHTML = "Geolocation is not supported by this browser.";}
    }

function showPosition(position) {
    x.innerHTML="Latitude: " + position.coords.latitude + 
    "<br>Longitude: " + position.coords.longitude;
}
</script>

</body>
</html>

【问题讨论】:

  • 您是否已将您的应用配置为允许使用 GPS?
  • 是的,已在 Android 清单中配置权限以允许精细和粗略的位置

标签: android xamarin webview xamarin.forms


【解决方案1】:

目前,当在手机或笔记本电脑上的 chrome 浏览器中打开时,webview/网站将返回 GPS 坐标,但在应用程序中不会。

您需要在 Droid 项目中为 WebView 使用自定义 WebChromeClient。请参考Android WebView Geolocation

在 Xamarin.Forms 中,您可以按照以下步骤完成此操作:

  1. 在 PCL 项目中为 WebView 创建自定义控件:

    public class GeoWebView:WebView
    {
    }
    

    并在 Xaml 中使用它:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:WebViewFormsDemo"
             x:Class="WebViewFormsDemo.MainPage">
    <local:GeoWebView 
        Source="https://danu6.it.nuigalway.ie/OliverInternetProgramming/project/Loginproject.html"></local:GeoWebView>
    

  2. 在 Droid 项目中为 GeoWebView 创建一个自定义渲染器,如下所示:

    [assembly:ExportRenderer(typeof(GeoWebView),typeof(GeoWebViewRenderer))]
    namespace WebViewFormsDemo.Droid
    {
        public class GeoWebViewRenderer:WebViewRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
                Control.Settings.JavaScriptEnabled = true;
                Control.SetWebChromeClient(new MyWebClient());
            }
        }
    
        public class MyWebClient : WebChromeClient
        {
            public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)
            {
                callback.Invoke(origin, true, false);
            }
        }
    }
    
  3. AndroidManifest.xml添加权限:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

然后您将在 webview 中正确获取您的位置。

【讨论】:

    【解决方案2】:

    Cheers Elvis 设法让一切正常运行,不得不进行一些小改动,因此将发布我所做的所有细节:

    在 App.xaml.cs 中:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using Xamarin.Forms;
    
    namespace WebViewFormsDemo
    {
        public partial class App : Application
        {
            public App()
            {
                InitializeComponent();
                MainPage = new MainPage();
            }
    
        protected override void OnStart()
        {
            // Handle when your app starts
        }
    
        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }
    
        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
    

    }

    在 MainPage.xaml 中确保您的网站是“https”

    <?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:WebViewFormsDemo"
                 x:Class="WebViewFormsDemo.MainPage">
    
      <local:GeoWebView
        Source="https:// --- Your Website ----></local:GeoWebView>
    
    </ContentPage>
    

    正如猫王所说,需要在 PLC 项目中创建自定义控件。右键单击并添加新的“类”来执行此操作。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    
    namespace WebViewFormsDemo
    {
        public class GeoWebView : WebView
        {
        }
    }
    

    然后在 Droid 类中创建一个自定义渲染。最初这里有一些错误,主要是缺少“使用”指令以及“程序集”中需要的关键字。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using Android.Webkit;
    
    [assembly: ExportRenderer(typeof(WebViewFormsDemo.GeoWebView), typeof(WebViewFormsDemo.Droid.GeoWebViewRenderer))]
    namespace WebViewFormsDemo.Droid
    {
        public class GeoWebViewRenderer : WebViewRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
                Control.Settings.JavaScriptEnabled = true;
                Control.SetWebChromeClient(new MyWebClient());
            }
        }
    
        public class MyWebClient : WebChromeClient
        {
            public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)
            {
                callback.Invoke(origin, true, false);
            }
        }
    }
    

    在进行了这些更改之后,一切都运行良好。再次感谢猫王!

    【讨论】:

    • 对我来说并不顺利。我按照你描述的做的很好。但是当 javascript 尝试获取地理位置时出现此错误:01-11 22:16:27.544 E/cr_LocationProvider(10680): Caught security exception while registering for location updates from the system. The application does not have sufficient geolocation permissions. 01-11 22:16:27.546 E/cr_LocationProvider(10680): newErrorAvailable application does not have sufficient geolocation permissions. 我已启用精细和粗略的位置权限。
    • 我相信当您以 API 23 或更高版本为目标时会发生这种情况。该代码在较低的 SDK 上运行良好。对于 Marshmellow 及更高版本,在某些时候需要通过用户对话框明确授予权限,但我不确定在哪里或如何。
    • 我在 c# 中使用它 - 遵循 James Montemagno 权限。这将添加您缺少的额外检查 var hasPermission = await UtilsPermissions.CheckPermissions(Permission.Location);
    • 请这个任何人都可以为 API 23 及更高版本工作?
    猜你喜欢
    • 1970-01-01
    • 2014-09-20
    • 2015-02-26
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多