位置情報を利用したページの表示
位置情報を利用したページは
アプリ利用者の位置情報を必要とするページのこと
JavascriptにGeolocation APIがあるので
これを使えるようにする
まずは、AndroidManifest.xmlへ権限を追加する
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
次に、JavaでGeoLocation APIの有効化
まずは、位置情報の取得の有効化
これで、Webページが位置情報をリクエストしてきたときに
アプリ側でリクエストを許可するかを決めることができる
まず、メンバ変数の定義
private WebView mWebView;
次に、onCreate()へWebView関連の処理追加
mWebView = new WebView(this); setContentView(mWebView); //Javascript有効化 mWebView.getSettings().setJavascriptEnabled(true); setupGeoLocation(mWebView); mWebView.setWebViewClient(new WebViewClient());
setupGeoLocation()は、ユーザー関数
つまり自作でつくる関数なので
これを追加する
private void setupGeoLocation(WebView webview){ WebSettings ws = webview.getSettings(); //位置情報取得の有効化 ws.setGeoLocationEnabled(true); //DB保存場所の指定 File databaseDir = getDir("databases", Context.MODE_PRIVATE); //保存場所がないなら新規作成 if(!databaseDir.exists()){ databaseDir.mkdirs(); } ws.setGeoLocationDatabasePath(databaseDir.getPath()); }
次に、位置情報取得許可を表示するためのダイアログ作成
Webページが位置情報のリクエストをすると
WebChromeClientクラスの
onGeoLocationPermissionShowPrompt()
が呼ばれる
このタイミングでダイアログを表示して
ユーザーに位置情報取得許可を促す
これで、許可されたら
GeoLocationPermissions.Callbackインスタンスの
invoke()を呼ぶことで
Webページは位置情報を取得できるようになる
このダイアログ作成処理をonCreate()へ追加する
mWebView.setWebChromeClient(new WebChromeClient(){ @Override public void onGeoLocationPermissionsShowPrompt(String origin, Callback callback){ GeoLocationPermissionDialog.newInstance(callback, origin).show(getFragmentManager(), GeoLocationPermissionDialog.FRG_TAG); } @Override public void onGeoLocationPermissionsHidePrompt(){ FragmentManager fm = new FragmentManager(); Fragment f = fm.findFragmentByTag(GeoLocationPermissionDialog.FRG_TAG); if(f != null){ GeoLocationPermissionDialog d = (GeoLocationPermissionDialog)f ; d.dismissAllowingStateLoss(); } } }); mWebView.loadUrl("http://位置情報取得許可するページのURL");
次に、ダイアログフラグメントの作成
public static class GeoLocationPermissionDialog extends DialogFragment{ public static final String FRG_TAG = GeoLocationPermissionDialog.class.getSimpleName(); public static final String EXTRA_ORIGIN = "extra.ORIGIN"; private GeoLocationPermissionDialog newInstance(GeoLocationPermissions.Callback callback, String origin){ GeoLocationPermissionDialog f = new GeoLocationPermissionDialog(); f.mCallback = callback; Bundle args = new Bundle(); args.putString(EXTRA_ORIGIN,origin); f.setArguments(args); return f; }
次に、ダイアログの設定
はい、いいえボタンの動作を定義
@Override public Dialog onCreateDialog(Bundle savedInstanceState){ AlertDialog.Builder = new AlertDialog.Builder(getActivity()); builder.setTitle("位置情報の要求"); builder.setMessage(String.format("このページはあなたの位置情報を求めてます¥n許可しますか?", getArguments().getString(EXTRA_ORIGIN))); builder.setPositiveButton("はい", new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which){ if(mCallback != null){ mCallback.invoke( getArguments().getString(EXTRA_ORIGIN),true, false); } mCallback = null; } }); builder.setNegativeButton("キャンセル", null); return builder.create(); } }
@Override public void onDismiss(DialogInterface dialog){ super.onDismiss(dialog); if(mCallback != null){ mCallback.invoke(getArguments().getString(EXTRA_ORIGIN), false, false); mCallback = null; } }
このクラスのinvoke()の引数は3つ
1つは、オリジン
オリジンとは、URLのうちの
スキーム
ホスト
ポートの組み合わせ
JavascriptやPHPやっているとわかりやすい
オリジンには
onGeoLocationPermissionsShowPromptハンドラの引数 origin を指定する
2つめの引数は、位置情報提供の許可、
拒否を表す真偽値
つまり許可ならtrue
拒否ならfalse
そして、3つめの引数が
今後も位置情報提供を記憶するかどうかの真偽値
つまり記憶するならtrue
記憶しないならfalse
となる