位置情報を利用したページの表示
位置情報を利用したページは
アプリ利用者の位置情報を必要とするページのこと
JavascriptにGeolocation APIがあるので
これを使えるようにする
まずは、AndroidManifest.xmlへ権限を追加する
1 2 | < uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" /> < uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION" /> |
次に、JavaでGeoLocation APIの有効化
まずは、位置情報の取得の有効化
これで、Webページが位置情報をリクエストしてきたときに
アプリ側でリクエストを許可するかを決めることができる
まず、メンバ変数の定義
1 | private WebView mWebView; |
次に、onCreate()へWebView関連の処理追加
1 2 3 4 5 6 7 8 | mWebView = new WebView( this ); setContentView(mWebView); //Javascript有効化 mWebView.getSettings().setJavascriptEnabled( true ); setupGeoLocation(mWebView); mWebView.setWebViewClient( new WebViewClient()); |
setupGeoLocation()は、ユーザー関数
つまり自作でつくる関数なので
これを追加する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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()へ追加する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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(); } } }); |
次に、ダイアログフラグメントの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } |
次に、ダイアログの設定
はい、いいえボタンの動作を定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @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(); } } |
1 2 3 4 5 6 7 8 9 10 11 | @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
となる