显示提示符以知道位置

时间:2022-11-11 21:15:39

I am using Xamarin WebView controller to display a web site (in both iOS/Android). The web site's home page prompts to access the device location. But that prompt is not showing when I have this website on a WebView (from the App). When I open this site on the browser, from the same mobile device it shows the message box. I am just wondering if it is possible to have such prompts on Xamarin WebView?

我正在使用Xamarin WebView controller来显示一个网站(iOS/Android都有)。网站的主页提示访问设备位置。但是当我在WebView(来自应用)上有这个网站时,那个提示符就不会显示出来。当我在浏览器上打开这个站点时,从相同的移动设备上显示了消息框。我想知道在Xamarin WebView上是否可以有这样的提示?

Here is an example prompt.

这里有一个示例提示符。

显示提示符以知道位置

This is all I have in the Xamarin app.

这就是我在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>

UPDATE 1

更新1

Android

安卓

I've tried the solution mentioned in this post, but still it doesn't show the prompt.

我已经尝试了这篇文章中提到的解决方案,但是仍然没有显示提示符。

WebViewRenderer.cs

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;
        }
    }
}

Manifest

清单

<?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

iOS

Tried NSLocationWhenInUseUsageDescription in the plist file, but no difference.

在plist文件中尝试了nslocationwhen inuseagedescription,但是没有区别。

Example App that does a similar thing

做类似事情的示例应用程序

显示提示符以知道位置

2 个解决方案

#1


3  

Updated answer (with code)

In case of Android - you will need a custom renderer for your WebView control. (ref: gist)

如果是Android -你需要一个自定义渲染器为你的WebView控件。(参考:要点)

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();
    }
}

Manifest permissions

Manifest权限

<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" />

Usage sample

使用示例

<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>

显示提示符以知道位置

And, in case of iOS, you need to set NSLocationWhenInUseUsageDescription description in the info.plist file.

而且,如果是iOS,你需要设置NSLocationWhenInUseUsageDescription描述的信息。plist文件。

显示提示符以知道位置

And it displays the prompt.

它会显示提示符。

显示提示符以知道位置

Complete code sample can be found at this link

完整的代码示例可以在这个链接中找到


Original answer

原来的答案

In case of Android - you should be able to resolve this by adding a platform-specific renderer for WebView and implement the permission handling by adding a custom WebChromeClient.

对于Android——您应该能够通过为WebView添加特定于平台的渲染器来解决这个问题,并通过添加自定义的WebChromeClient实现权限处理。

In case of iOS - you need to add NSLocationWhenInUseUsageDescription description in your info plist

如果是iOS,你需要在你的info plist中添加NSLocationWhenInUseUsageDescription描述。

#2


1  

But that prompt is not showing when I have this website on a WebView (from the App).

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

If I got it right, you're wrapping this in an app. That's not the expected user experience from a mobile app. your app should use the platform(e.g iOS,Android) location permissions in order to get the user approval.

如果我猜对了,你是在一个应用中包装这个东西。这不是移动应用所期望的用户体验。你的应用应该使用平台(e)。g iOS,Android)定位权限,以获得用户批准。

Xamarin will let you access Location on each platform quite differently. If the Xamarin app has access to location than the webview should inherit these permissions. So it might worth trying this recipe and try accsing location before opening the webview itself

Xamarin将让您以完全不同的方式访问每个平台上的位置。如果Xamarin应用程序有访问位置的权限,那么webview应该继承这些权限。因此,在打开webview之前,不妨尝试一下这个食谱和accsing location

#1


3  

Updated answer (with code)

In case of Android - you will need a custom renderer for your WebView control. (ref: gist)

如果是Android -你需要一个自定义渲染器为你的WebView控件。(参考:要点)

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();
    }
}

Manifest permissions

Manifest权限

<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" />

Usage sample

使用示例

<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>

显示提示符以知道位置

And, in case of iOS, you need to set NSLocationWhenInUseUsageDescription description in the info.plist file.

而且,如果是iOS,你需要设置NSLocationWhenInUseUsageDescription描述的信息。plist文件。

显示提示符以知道位置

And it displays the prompt.

它会显示提示符。

显示提示符以知道位置

Complete code sample can be found at this link

完整的代码示例可以在这个链接中找到


Original answer

原来的答案

In case of Android - you should be able to resolve this by adding a platform-specific renderer for WebView and implement the permission handling by adding a custom WebChromeClient.

对于Android——您应该能够通过为WebView添加特定于平台的渲染器来解决这个问题,并通过添加自定义的WebChromeClient实现权限处理。

In case of iOS - you need to add NSLocationWhenInUseUsageDescription description in your info plist

如果是iOS,你需要在你的info plist中添加NSLocationWhenInUseUsageDescription描述。

#2


1  

But that prompt is not showing when I have this website on a WebView (from the App).

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

If I got it right, you're wrapping this in an app. That's not the expected user experience from a mobile app. your app should use the platform(e.g iOS,Android) location permissions in order to get the user approval.

如果我猜对了,你是在一个应用中包装这个东西。这不是移动应用所期望的用户体验。你的应用应该使用平台(e)。g iOS,Android)定位权限,以获得用户批准。

Xamarin will let you access Location on each platform quite differently. If the Xamarin app has access to location than the webview should inherit these permissions. So it might worth trying this recipe and try accsing location before opening the webview itself

Xamarin将让您以完全不同的方式访问每个平台上的位置。如果Xamarin应用程序有访问位置的权限,那么webview应该继承这些权限。因此,在打开webview之前,不妨尝试一下这个食谱和accsing location