位置情報を利用したページの表示
位置情報を利用したページは
アプリ利用者の位置情報を必要とするページのこと
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
となる