位置情報を利用したページの表示

位置情報を利用したページの表示

位置情報を利用したページは
アプリ利用者の位置情報を必要とするページのこと

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();
}
}
});
 
mWebView.loadUrl("http://位置情報取得許可するページのURL");

次に、ダイアログフラグメントの作成

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
となる

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です