0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Androidアプリ開発: Google Mapsで位置情報と移動履歴を表示するアプリの作成

Posted at

本記事では、AndroidアプリにGoogle Mapsと位置情報取得機能を組み込み、リアルタイムで現在位置を表示しつつ、移動軌跡を地図上に表示する方法を紹介します。


Androidの位置情報パーミッション解説

  1. ACCESS_FINE_LOCATION

概要: 高精度の位置情報(GPSやWi-Fi、携帯基地局など)を取得するための権限。

用途: ナビアプリ、ランニングトラッカー、精密な地図サービスなど。

特徴: 数メートル単位の精度。


2.ACCESS_COARSE_LOCATION

概要: 粗い位置情報(Wi-Fiや携帯基地局)を取得するための権限。

用途: おおよその現在地で十分なサービス(天気、周辺情報など)。

特徴: 数百メートル〜数キロの精度。


3.ACCESS_BACKGROUND_LOCATION

概要: アプリがバックグラウンドでも位置情報を取得するための権限。

用途: 運動ログ、デリバリー追跡、防犯サービスなど。

注意点:

Android 10(API 29)以降で導入。

ACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATIONとセットで必要。

ユーザーに強い理由を提示しないと許可されにくい。


注意事項

Android 6.0(API 23)以降は実行時パーミッションの取得が必須。

ACCESS_BACKGROUND_LOCATIONはユーザー体験やプライバシーに大きく関わるため、Google Playの審査が厳しいです。


アプリ概要

  • 現在地の緯度・経度、高度、精度、速度、進行方向、時刻を表示
  • Google Maps上に現在地マーカーと円(半径30m)を表示
  • 過去の位置履歴をPolylineとして地図に描画
  • ACCESS_FINE_LOCATION を使用して高精度な位置情報を取得

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/drone"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/drone_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Demo0430"
        tools:targetApi="31">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="YOUR_API_KEY_HERE" />
    </application>
</manifest>

MainActivity.kt の実装ポイント

  • FusedLocationProviderClient を使用して位置情報を取得
  • LocationCallback で位置更新を受け取り、UI・地図を更新
  • Polyline で移動の軌跡を地図に描画
override fun onLocationResult(result: LocationResult) {
    val location = result.lastLocation ?: return

    // 情報表示用のテキスト作成
    val timeStr = SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()).format(Date(location.time))
    val info = """
        緯度: ${location.latitude}
        経度: ${location.longitude}
        高度: ${location.altitude} m
        精度: ${location.accuracy} m
        速度: ${location.speed} m/s
        進行方向: ${location.bearing} °
        時刻: $timeStr
    """.trimIndent()

    locationText.text = info

    val latLng = LatLng(location.latitude, location.longitude)

    // マーカー・サークルの更新
    currentMarker?.remove()
    currentMarker = googleMap.addMarker(
        MarkerOptions().position(latLng).title("現在地")
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
    )

    currentCircle?.remove()
    currentCircle = googleMap.addCircle(
        CircleOptions()
            .center(latLng)
            .radius(30.0)
            .strokeColor(Color.RED)
            .fillColor(0x30FF0000)
            .strokeWidth(2f)
    )

    // 軌跡描画
    pathPoints.add(latLng)
    googleMap.addPolyline(
        PolylineOptions().addAll(pathPoints).color(Color.BLUE).width(8f)
    )

    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17f))
}

パーミッション確認とリクエスト

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
    == PackageManager.PERMISSION_GRANTED
) {
    startLocationUpdates()
} else {
    permissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}

activity_main.xml - UIレイアウト

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="8dp">

    <TextView
        android:id="@+id/textLocation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="位置情報取得中..."
        android:textSize="16sp"
        android:padding="8dp" />

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

strings.xml

<resources>
    <string name="app_name">demo0430</string>
    <string name="location_loading">位置情報を取得中...</string>
    <string name="location_error">位置情報を取得できませんでした</string>
</resources>

build.gradle.kts(アプリモジュール)

android {
    namespace = "com.example.demo0430"
    compileSdk = 35

    defaultConfig {
        applicationId = "com.example.demo0430"
        minSdk = 34
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = "11"
    }
}

dependencies {
    implementation("com.google.android.gms:play-services-location:21.0.1")
    implementation("com.google.android.gms:play-services-maps:18.1.0")

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.material)
    implementation(libs.androidx.activity)
    implementation(libs.androidx.constraintlayout)
}

補足と改善ポイント

  • fetchLocation()onLocationResult() 内でも SecurityExceptiontry-catch で明示的に扱うとより堅牢になります。
  • accuracy は環境により誤差が出るため、ユーザーに注意書きを加えると親切です。
  • 軌跡データ(pathPoints)をRoomやSharedViewModelで保存・共有することで履歴タブなどの実装にも応用可能です。

おわりに

このアプリをベースに、今後は以下の機能拡張も可能です:

  • 履歴表示(リスト/地図)機能
  • バックグラウンドでの位置取得
  • 位置情報のAWS等へのアップロード

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?