显示提示以了解位置 [英] Show Prompt to know the location

查看:60
本文介绍了显示提示以了解位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Xamarin WebView控制器显示网站(在iOS/Android中).该网站的主页提示您访问设备位置.但是,当我在WebView(通过App)上拥有此网站时,该提示没有显示.当我在浏览器中打开此站点时,它从同一移动设备显示消息框.我只是想知道是否有可能在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

我已经尝试了帖子,但仍然不显示提示.

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 ,则-您需要为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();
    }
}

清单权限

<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描述.

并显示提示.

完整的代码示例可以在此链接

中找到


原始答案

在Android的情况下-您应该能够通过为WebView添加特定于平台的渲染器来解决此问题,并通过以下方式实现权限处理添加自定义WebChromeClient .

在iOS中-您需要在信息plist中添加 NSLocationWhenInUseUsageDescription描述

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?

Here is an example prompt.

This is all I have in the Xamarin app.

<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

Android

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

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

Tried NSLocationWhenInUseUsageDescription in the plist file, but no difference.

解决方案

Updated answer (with code)

In case of Android - you will need a custom renderer for your WebView control. (ref: 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();
    }
}

Manifest permissions

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

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.

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

这篇关于显示提示以了解位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆