[2016-11-19 カスタムレンダラーで解決できたので解決法を追記]
やりたいこと
Xamarin.Forms.WebView
にページを表示して、そのページ内のJSでGeoLocation APIを使いたい:
<script>
navigator.geolocation.getCurrentPosition(function(position) {
alert("OK");
console.log(position);
});
</script>
問題
iOSでは特に何もしなくても問題なくできたのですが、Androidではこれができない。
ACCESS_COARSE_LOCATION
, ACCESS_FINE_LOCATION
の許可をつけてもダメ。
実行時にユーザーに許可を求めるポップアップが出てこない。
解決法
カスタムレンダラーを作って位置情報取得を許可する。
具体的には下記のファイルを.Droid
のプロジェクトに追加するだけでOK。
CustomWebViewRenderer_Droid.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(WebView), typeof(CustomWebView.Droid.CustomWebViewRenderer))]
namespace CustomWebView.Droid
{
public class CustomWebViewRenderer : Xamarin.Forms.Platform.Android.WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
// WebViewClientまで上書きしてしまうとNavigatedやNavigatingイベントが発生しなくなってしまう
// WebChromeClientを上書きするだけでGeoLocation APIは使えるようになる
//Control.SetWebViewClient(new CustomWebViewClient());
Control.SetWebChromeClient(new CustomWebChromeClient());
}
}
//class CustomWebViewClient : Android.Webkit.WebViewClient
//{
// public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, string url)
// {
// return false;
// }
//}
// Xamarin FormsのデフォルトのWebChromeClientを継承する
// https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/WebViewRenderer.cs
class CustomWebChromeClient : Xamarin.Forms.Platform.Android.FormsWebChromeClient
{
public override void OnGeolocationPermissionsShowPrompt(string origin, Android.Webkit.GeolocationPermissions.ICallback callback)
{
callback.Invoke(origin, true, false);
}
}
}
参考
http://android.keicode.com/basics/webview-html5-geolocation.php
この解決法のサンプルプロジェクト:https://github.com/aoyama-val/WebViewTest3