【问题标题】:Show Prompt to know the location显示提示知道位置
【发布时间】:2017-11-21 14:08:33
【问题描述】:

我正在使用 Xamarin WebView 控制器来显示网站(在 iOS/Android 中)。网站主页提示访问设备位置。但是,当我在 WebView(来自应用程序)上有这个网站时,没有显示该提示。当我在浏览器上打开此站点时,它会从同一移动设备显示消息框。我只是想知道是否可以在 Xamarin WebView 上有这样的提示?

这是一个示例提示。

这就是我在 Xamarin 应用程序中的全部内容。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:nCollar"
             x:Class="nCollar.MainPage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <OnPlatform.iOS>0,20,0,0</OnPlatform.iOS>
            <OnPlatform.Android>0,0,0,0</OnPlatform.Android>
            <OnPlatform.WinPhone>0,0,0,0</OnPlatform.WinPhone>
        </OnPlatform>
    </ContentPage.Padding>

    <WebView x:Name="webView"
                 Grid.Row="0"
                 VerticalOptions="FillAndExpand" 
                 Source="https://www.ncollar.com.au/"/>

</ContentPage>

更新 1

Android

我已经尝试了this帖子中提到的解决方案,但仍然没有显示提示。

WebViewRenderer.cs

using Android.Webkit;
using Xamarin.Forms.Platform.Android;

[assembly: Xamarin.Forms.ExportRenderer(typeof(TestApp.Controls.WebView), typeof(TestApp.Droid.Renderers.WebViewRenderer))]
namespace TestApp.Droid.Renderers
{
    public class WebViewRenderer : Xamarin.Forms.Platform.Android.WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if (this.Control == null)
            {
                return;
            }

            var webView = this.Element as TestApp.Controls.WebView;
            if (webView == null)
            {
                return;
            }


           // webView. ings.JavaScriptEnabled = true;
            this.Control.Settings.DomStorageEnabled = true;
            this.Control.Settings.DisplayZoomControls = true;
            this.Control.Settings.BuiltInZoomControls = true;
            this.Control.Settings.SetGeolocationEnabled(true);
            this.Control.Settings.JavaScriptCanOpenWindowsAutomatically = true;

            this.Control.SetWebViewClient(new GeoWebViewClient());
            this.Control.SetWebChromeClient(new GeoWebChromeClient());
        }
    }

    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, string url)
        {
            view.LoadUrl(url);
            return true;
        }
    }
}

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-sdk android:minSdkVersion="15" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application android:label="TestApp.Android"></application>
</manifest>

iOS

在 plist 文件中尝试了NSLocationWhenInUseUsageDescription,但没有区别。

【问题讨论】:

    标签: android ios xamarin webview xamarin.forms


    【解决方案1】:

    更新答案(带代码)

    如果是 Android - 您需要为您的 WebView 控件使用自定义渲染器。 (参考:gist

    public class ExtendedWebViewRenderer : WebViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);
    
            if (e.OldElement != null || Element == null)
            {
                return;
            }
    
            Control.Settings.JavaScriptEnabled = true;
            Control.Settings.SetGeolocationEnabled(true);
            Control.Settings.SetGeolocationDatabasePath(Control.Context.FilesDir.Path);
    
            Control.SetWebViewClient(new CustomWebViewClient());
            Control.SetWebChromeClient(new CustomChromeClient(Control.Context));
        }
    }
    
    public class CustomWebViewClient : WebViewClient
    {
        public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, string url)
        {
            view.LoadUrl(url);
            return true;
        }
    }
    
    public class CustomChromeClient : WebChromeClient
    {
        private readonly Context _context;
    
        public CustomChromeClient(Context context)
        {
            _context = context;
        }
    
        public override void OnGeolocationPermissionsShowPrompt(string origin, GeolocationPermissions.ICallback callback)
        {
            const bool remember = false;
            var builder = new 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();
        }
    }
    

    清单权限

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

    使用示例

    <StackLayout Margin="30" BackgroundColor="#ededed">
        <Label Text="WebView location prompt sample" Margin="15" HorizontalOptions="Center" />
        <local:ExtendedWebView x:Name="webView" Source="https://www.yellowpages.com/" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
    </StackLayout>
    

    并且,如果是 iOS,您需要在 info.plist 文件中设置 NSLocationWhenInUseUsageDescription 描述。

    它会显示提示。

    完整的代码示例可以在this link找到


    原答案

    对于 Android - 您应该能够通过为 WebView 添加特定于平台的渲染器并实现权限处理 by adding a custom WebChromeClient 来解决此问题。

    如果是 iOS - 您需要在信息列表中添加 NSLocationWhenInUseUsageDescription description

    【讨论】:

    • 我必须对此进行研究并自己进行测试,然后才能回复您。 @yuri-s 关于在回调之前显示提示的建议没有成功吗?
    • 我对 Xamarin 相当陌生,我已经尝试了几天,但没有运气。您是唯一为解决方案提供任何提示的人。我会给你赏金。请看一下,如果您知道为什么这不起作用,请告诉我...谢谢!
    • @SharadaGururaj 很好的链接到我正在查看的相同答案。如果您在没有实施自定义权限请求对话框的情况下解决了这个问题,请抄送我。我有兴趣看看如何。谢谢。
    • @CharithJ:使用工作示例更新了答案。在 iOS 中进行测试时 - 请确保重置您的隐私设置以显示提示。在android的情况下,每次都会显示提示,因为我们将remember设置为false。
    • @SharadaGururaj 干得好,但它不是 Android 的答案。我总是说你需要自己的对话。但是对于小于 23 的 API,甚至不需要,因为清单中的权限将启用访问,因此无需调用回调。对于 API 23,您需要的不仅仅是对话和回调。您需要实际请求权限。所以代码工作得很好,但你不需要所有这些:-) 问题是“表单吞下提示”。答案是“形式不会吞下,你需要自己实现”,你做到了。干得好
    【解决方案2】:

    但是当我在 WebView(来自应用程序)上有这个网站时,没有显示该提示。

    如果我没看错,你就是将它封装在一个应用程序中。 这不是移动应用程序的预期用户体验。您的应用应使用平台(例如 iOS、Android)位置权限以获得用户批准。

    Xamarin 将允许您以完全不同的方式访问每个平台上的位置。如果 Xamarin 应用程序有权访问位置,则 web 视图应继承这些权限。所以可能值得尝试this recipe 并在打开 web 视图本身之前尝试访问位置

    【讨论】:

    • :我同意这个解决方案并不理想。但是,有很多应用程序使用这种方法(至少在开始时)。还有一些这样的应用程序足以显示该提示。我正在尝试做同样的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多