显示提示知道位置

时间:2017-06-19 11:19:17

标签: android ios xamarin webview xamarin.forms

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

以下是示例提示。

enter image description here

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

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

更新1

的Android

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

WebViewRenderer.cs

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

清单

NSLocationWhenInUseUsageDescription

的iOS

在plist文件中尝试/* Call stack, this doesn't work */ const btn = document.createElement('BUTTON') const textLabel = document.createTextNode('Play') const audio = new window.Audio() audio.src = 'https://raw.githubusercontent.com/vnglst/autoplay-tutorial/master/mp3/winamp.mp3' // audio.controls = true btn.appendChild(textLabel) document.getElementById('root').appendChild(btn) document.getElementById('root').appendChild(audio) btn.onclick = e => { window .fetch(`https://api.github.com/repos/vnglst/autoplay-tutorial/contents/mp3/modem-sound.mp3`) .then(resp => resp.json()) .then(json => { audio.src = json.download_url audio.play() }) },但没有区别。

2 个答案:

答案 0 :(得分:3)

更新了答案(带代码)

如果是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>

android output

而且,对于iOS ,,您需要在NSLocationWhenInUseUsageDescription文件中设置info.plist说明。

info.plist

并显示提示。

ios output

  

可以在this link

找到完整的代码示例

原始回答

如果是Android,您应该可以通过为WebView添加特定于平台的渲染器来解决此问题,并实现权限处理by adding a custom WebChromeClient

如果是iOS,则需要在信息播放器中添加NSLocationWhenInUseUsageDescription description

答案 1 :(得分:1)

  

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

如果我做对了,你就可以在应用中包装它了。 这不是移动应用的预期用户体验。您的应用应使用平台(例如iOS,Android)位置权限,以获得用户的批准。

Xamarin将让您以完全不同的方式访问每个平台上的位置。如果Xamarin应用程序可以访问位置,那么webview应该继承这些权限。所以值得尝试this recipe并尝试在打开webview本身之前获取位置