使用ツール
Android Studio Flamingo | 2022.2.1 Patch 2
1. 位置情報取得ライブラリの組み込み
1-1. Android Studio に Google Play Services を追加する。
(開発環境に追加するので 1 回実施すれば OK)1-2. プロジェクトに Location ライブラリを追加する。
メニュー - File - Settings - Appearance & Behavor - SystemSettings > Android SDK
SDK Tools タブ
下記ツールにチェックを入れ、 ボタンをクリックする。
☑ Google Play services
メニュー - File - Project Structure... を選択する。1-3. 追加したライブラリをプロジェクトに反映させる。
1-2-1. Project Structure ダイアログ
Dependencies
Modules - app を選択ボタンをクリックして Project Structure ダイアログを閉じる。
Declared Dependencies の Dependency に play-services-location:xx.x.x が存在しないことを確認
(もし存在していたら、すでに Location ライブラリが追加済みなので ボタンをクリックする)
Declared Dependencies の「+」から Library Dependency を選択する。
1-2-1-1. Add Library Dependency ダイアログ
Step 1. で を記入して をクリックする。Dependency に play-services-location:xx.x.x があることを確認して をクリックする。
| Artifact Name | から play-services-location を選択して をクリックする。
このとき、Versions から最新に近い番号を選択する。
(本稿記述時は 21.0.1 が最新。AndroidStudio のバージョンが古い場合は最新以外を選択する)
メニュー - File - Sync Project with Gradle Files を選択する。
2. マニフェストの記述。
マニフェストファイルに位置情報を使用する宣言を記述する。
要素名 内容 備考 マニフェスト Android > app > manifests > AndroidManifest.xml - 要求機能1 android.permission.ACCESS_COARSE_LOCATION 精度の低い情報 要求機能2 android.permission.ACCESS_FINE_LOCATION 精度の高い情報
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <application //~ 省略 ~ </application> </manifest>
3. アクティビティにテキストボックスを配置する。
activity_main にテキストボックスを配置する。(位置情報をこのテキストボックスに表示する)
要素名 内容 備考 アクティビティ Android > app > res > layout > activity_main.xml - 部品 種類 TextView - id textView プログラムから R.id.textView として参照される。
4. 位置情報取得ライブラリの利用。
プログラムを分かりやすくするため、最初はわざと非効率的に作成します。
位置情報取得ライブラリは、位置が変化すると自動的に通知が出るように作られています。
プログラムはこの通知に合わせて作成する必要があり、コールバッククラス (という名前のプログラム)
を登録することにより、通知のたびにプログラムが動作するように構成します。
4-1. コールバッククラスを追加する。
クラス MainActivity (MainActivity.java) の中 (onCreate と同レベル) に以下を記述する。4-2. コールバッククラスを登録する。
// 位置情報のコールバッククラスを定義 private class OnLocationCallback extends LocationCallback { @Override public void onLocationResult(@NonNull LocationResult locationResult) { Location location = locationResult.getLastLocation(); // 位置情報オブジェクトを取得 if(location == null) return; // 位置情報オブジェクトが取得できなければ何もしない double latitude = location.getLatitude(); // 緯度を取得 double longitude = location.getLongitude(); // 経度を取得 String notice = "現在位置: " + latitude + ", " + longitude; TextView tv = findViewById(R.id.textView); tv.setText(notice); } }
クラス MainActivity のメソッド onCreate の中に以下を記述する。(setContentView より後ろ)
(これは下記 5-1 で組み替える)
*2 リクエストコードは onRequestPermissionsResult() が呼ばれたときに自ら識別するための数値。自由に定義して良い。
// 位置情報許可要求のダイアログを表示する。*1 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { String[] permissions = { android.Manifest.permission.ACCESS_FINE_LOCATION, // 高精度計測を要求 android.Manifest.permission.ACCESS_COARSE_LOCATION // 低精度計測を要求 }; final int REQ_CODE = 1; // リクエストコードは自由な値を設定する。*2 ActivityCompat.requestPermissions(this, permissions, REQ_CODE); } // 位置情報の計測条件を用意 (精度を高精度、インターバルを 3 秒にしている) final long INTERVAL = 3000; LocationRequest.Builder builder = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, INTERVAL); LocationRequest locReq; // import に注意。*3 locReq = builder.build(); // 位置情報のコールバッククラスを用意 OnLocationCallback locCallback; locCallback = new OnLocationCallback(); // 位置情報のコールバッククラスを登録 (計測開始) FusedLocationProviderClient flpClient; flpClient = LocationServices.getFusedLocationProviderClient(this); flpClient.requestLocationUpdates(locReq, locCallback, Looper.getMainLooper());
onRequestPermissionsResult() は、ユーザに権限を要求した結果が通知されるメソッド。(許可・不許可が通知される)
本稿では記述していない。記述する場合はアノテーション @Override を使用して記述する。
*3 クラス LocationRequest には下記の 2 種類があります。
import 文を確認し、上記 1 で追加した Location ライブラリのモジュールを有効にします。
✗ android.location.LocationRequest← 標準モジュール ✓ com.google.android.gms.location.LocationRequest ← 上記 1 で組み込んだモジュール
5. コールバッククラスの組み換え
GPS (Global Positioning System) を利用すると、激しく電力を消費します。
これを軽減するため、非表示の時にコールバック呼び出しを停止します。
5-1. メソッド onCreate の書き換えと onResume, onPause を追加。
クラス MainActivity (MainActivity.java) の中に以下を記述する。(*3 *4 *5 *6 を移設)
public class MainActivity extends AppCompatActivity {
LocationRequest locReq; // onCreate からここへ移設した。*3 OnLocationCallback locCallback; // onCreate からここへ移設した。*4 FusedLocationProviderClient flpClient; // onCreate からここへ移設した。*5
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
// 位置情報許可要求のダイアログを表示する。 if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { String[] permissions = { android.Manifest.permission.ACCESS_FINE_LOCATION, // 高精度計測を要求 android.Manifest.permission.ACCESS_COARSE_LOCATION // 低精度計測を要求 }; final int REQ_CODE = 1; ActivityCompat.requestPermissions(this, permissions, REQ_CODE); } // 位置情報の計測条件を用意 (精度を高精度、インターバルを 3 秒にしている) final long INTERVAL = 3000; LocationRequest.Builder builder = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, INTERVAL); //LocationRequest locReq;→ *3 onCreate の外に移設した。 locReq = builder.build(); // コールバッククラスを用意 //OnLocationCallback locCallback;→ *4 onCreate の外に移設した。 locCallback = new OnLocationCallback(); // コールバッククラスを登録 (計測開始) //FusedLocationProviderClient flpClient;→ *5 onCreate の外に移設した。 flpClient = LocationServices.getFusedLocationProviderClient(this); //flpClient.requestLocationUpdates(locReq, locCallback, Looper.getMainLooper());→ *6 onResume() へ移設した。
}
@Override protected void onResume() { super.onResume(); // ↓ requestLocationUpdates に警告が付加されるが正常に動作する。 // 位置情報許可要求 (上記 *1 の if ブロック) をここにまるごと移動させると警告が消える。 // 本来はここにあるべきだが説明の便宜上、移動していない。 // コールバッククラスを登録 (計測開始) ← onCreate から移設。*6 flpClient.requestLocationUpdates(locReq, locCallback, Looper.getMainLooper()); } @Override protected void onPause() { super.onPause(); // コールバッククラスを削除 (計測停止) ← 新規作成。 flpClient.removeLocationUpdates(locCallback); }
}