位置情報の取得
〜 Android Studio の使い方 6 〜
2023-04-20 作成 福島
TOP > androidstudio > location

使用ツール

    Android Studio Flamingo | 2022.2.1 Patch 2  


1. 位置情報取得ライブラリの組み込み

1-1. Android Studio に Google Play Services を追加する。
(開発環境に追加するので 1 回実施すれば OK)
メニュー -  File  -  Settings  -  Appearance & Behavor  -  SystemSettings  >  Android SDK 
SDK Tools タブ
下記ツールにチェックを入れ、 ボタンをクリックする。
☑ Google Play services
1-2. プロジェクトに Location ライブラリを追加する。
メニュー -  File  -  Project Structure...  を選択する。

1-2-1. Project Structure ダイアログ
 Dependencies 
 Modules  -  app  を選択
 Declared Dependencies  Dependency play-services-location:xx.x.x が存在しないことを確認
(もし存在していたら、すでに Location ライブラリが追加済みなので ボタンをクリックする)

 Declared Dependencies  の「」から  Library Dependency  を選択する。

1-2-1-1. Add Library Dependency ダイアログ
Step 1. で を記入して をクリックする。

| Artifact Name | から  play-services-location  を選択して をクリックする。
このとき、Versions から最新に近い番号を選択する。
(本稿記述時は 21.0.1 が最新。AndroidStudio のバージョンが古い場合は最新以外を選択する)
 Dependency  play-services-location:xx.x.x  があることを確認して をクリックする。
ボタンをクリックして Project Structure ダイアログを閉じる。
1-3. 追加したライブラリをプロジェクトに反映させる。
メニュー -  File  -  Sync Project with Gradle Files  を選択する。


2. マニフェストの記述。

マニフェストファイルに位置情報を使用する宣言を記述する。
要素名内容備考
マニフェスト Android  >  app  >  manifests  > AndroidManifest.xml-
要求機能1android.permission.ACCESS_COARSE_LOCATION精度の低い情報
要求機能2android.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-
idtextViewプログラムから R.id.textView として参照される。


4. 位置情報取得ライブラリの利用。

プログラムを分かりやすくするため、最初はわざと非効率的に作成します。

位置情報取得ライブラリは、位置が変化すると自動的に通知が出るように作られています。
プログラムはこの通知に合わせて作成する必要があり、コールバッククラス (という名前のプログラム)
を登録することにより、通知のたびにプログラムが動作するように構成します。

4-1. コールバッククラスを追加する。
クラス MainActivity (MainActivity.java) の中 (onCreate と同レベル) に以下を記述する。
// 位置情報のコールバッククラスを定義
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);
    }
}
4-2. コールバッククラスを登録する。
クラス MainActivity のメソッド onCreate の中に以下を記述する。(setContentView より後ろ)
(これは下記 5-1 で組み替える)
// 位置情報許可要求のダイアログを表示する。*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());
*2 リクエストコードは onRequestPermissionsResult() が呼ばれたときに自ら識別するための数値。自由に定義して良い。
   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); }
}