Kotlinで現在地を取得するたった10の方法 – Japanシーモア

Kotlinで現在地を取得するたった10の方法

Kotlinのロゴと、地図上のピンマークを表すイメージKotlin
この記事は約24分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

スマートフォンの普及とともに、現在地の取得機能は多くのアプリケーションで一般的に利用されるようになりました。

特にAndroidアプリ開発でよく使われるプログラミング言語「Kotlin」を使用して、この位置情報の取得をどのように実現するのか、多くの開発者や学習者が知りたいと思っていることでしょう。

この記事を読めば、Kotlinで現在地を取得する10の方法をマスターすることができるようになります。

初心者の方でもステップバイステップで学べる内容となっていますので、最後までじっくりと読み進めてみてください。

●Kotlinとは?

Kotlinは、2011年にJetBrains社によって開発された、静的型付けのプログラミング言語です。

Javaとの互換性を持ちつつ、より簡潔で表現力が豊かなコードを書くことができるとして、近年のAndroidアプリ開発で主流となっています。

○Kotlinの特徴

Kotlinは次のような特徴を持っています。

  • 簡潔さ:Kotlinは、冗長なコードを減らし、より読みやすく、簡潔にコードを書くことができます。
  • Javaとの互換性:KotlinはJavaと100%互換性があります。既存のJavaコードとKotlinのコードを一緒に使うことも、JavaからKotlinへの移行もスムーズに行えます。
  • 安全性:Kotlinは、Null参照を原則として排除し、多くの一般的なプログラミングミスをコンパイル時にキャッチします。
  • 拡張性:Kotlinは、既存のクラスに新しい機能を追加するための拡張関数を提供します。これにより、既存のライブラリやフレームワークを拡張して、自分のニーズに合わせた関数を追加することができます。

●Androidでの位置情報の取得方法

Androidアプリケーションにおいて、ユーザーの現在地を取得する機能は多くのアプリで利用されています。

天気予報アプリや地図アプリ、交通情報サービスなど、多岐にわたるジャンルのアプリで現在地情報は活用されています。

では、Androidで位置情報を取得するためにはどのような手続きや設定が必要なのでしょうか。

○位置情報の取得に必要な許可

Androidアプリケーションで位置情報を取得する前に、必ずユーザーからの許可を得る必要があります。

具体的には、AndroidManifest.xmlファイルに必要なパーミッションを追加することで、位置情報の取得を許可してもらいます。

AndroidManifest.xmlに次のパーミッションを追加します。

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

上記のパーミッションを追加した後は、実際にアプリを起動する際にユーザーに許可を求めるダイアログが表示されます。

ユーザーが許可を与えると、その後の操作で位置情報の取得が可能となります。

○位置情報の精度と種類

Androidで位置情報を取得する際には、2つの精度の違う位置情報を取得することができます。

一つはACCESS_FINE_LOCATIONを使用した高精度な位置情報、もう一つはACCESS_COARSE_LOCATIONを使用した大まかな位置情報です。

  • 高精度な位置情報:GPSを使用して取得する位置情報で、非常に詳細な位置情報を取得することができます。ただし、GPSの取得には時間がかかることや室内では正確な情報が取得しづらいというデメリットがあります。
  • 大まかな位置情報:Wi-Fiやモバイルネットワークを使用して位置情報を取得します。GPSに比べて精度は落ちますが、速度が速いため、大まかな位置情報を素早く取得したい場合に利用されます。

どちらの位置情報を取得するかは、アプリの目的やユーザーのニーズに応じて選択することができます。

●Kotlinで現在地を取得する方法10選

Kotlinを使用してAndroidアプリケーションで現在地を取得する方法は多岐にわたります。

ここでは、その中から10の主要な方法をピックアップし、サンプルコードを交えながら徹底的に解説します。

○サンプルコード1:基本的な位置情報の取得

Androidアプリケーションで最も基本的な方法で位置情報を取得する方法を考えてみましょう。

import android.content.Context
import android.location.LocationManager

// 位置情報マネージャの取得
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

// GPS_PROVIDERからの位置情報の最後の情報を取得
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)

このコードでは、システムサービスからLocationManagerを取得しています。

そして、getLastKnownLocationメソッドを使用して、GPSから最後に取得された位置情報を取得しています。

このコードを実行すると、ユーザーの最後の位置情報がlocationオブジェクトに格納され、緯度や経度を取得することができます。

○サンプルコード2:更新される位置情報の取得

次に、ユーザーの位置が変動するたびにその情報を取得する方法を見てみましょう。

import android.location.Location
import android.location.LocationListener
import android.os.Bundle

val locationListener = object : LocationListener {
    override fun onLocationChanged(location: Location?) {
        // 位置情報が変更された際の処理
        val latitude = location?.latitude
        val longitude = location?.longitude
    }

    override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}

    override fun onProviderEnabled(provider: String?) {}

    override fun onProviderDisabled(provider: String?) {}
}

// 位置情報の変更を検知するリスナーを登録
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, locationListener)

このコードでは、LocationListenerを実装しています。

onLocationChangedメソッドは位置情報が変更されたときに呼び出され、その中で新しい位置情報を取得しています。

このコードを実行すると、ユーザーの位置が変動するたびに、新しい位置情報がlatitudeおよびlongitude変数に更新されます。

○サンプルコード3:特定の間隔で位置情報を取得

リアルタイムの位置情報追跡には適していますが、すべての位置変動を検知する必要がない場合や、バッテリー消費を抑えたい場合、特定の間隔での位置情報取得が有効です。

ここでは、指定した時間間隔と距離間隔で位置情報を取得する方法を紹介します。

import android.location.Location
import android.location.LocationListener
import android.os.Bundle

val locationListener = object : LocationListener {
    override fun onLocationChanged(location: Location?) {
        // 位置情報が変更された際の処理
        val latitude = location?.latitude
        val longitude = location?.longitude
    }

    override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}

    override fun onProviderEnabled(provider: String?) {}

    override fun onProviderDisabled(provider: String?) {}
}

// 10分(600,000ミリ秒)ごと、または100m移動するごとに位置情報を取得する設定
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 600000, 100f, locationListener)

このコードでは、requestLocationUpdatesメソッドの第二引数と第三引数で、時間間隔と距離間隔を指定しています。

具体的には、10分ごと、または100m移動するごとにonLocationChangedメソッドが呼び出され、新しい位置情報が取得されます。

このようにして、位置情報の更新頻度を制御することで、アプリの動作をより柔軟にし、バッテリーの消費も抑えることが可能です。

○サンプルコード4:バックグラウンドでの位置情報取得

アプリがバックグラウンドにあるときでも位置情報を取得したい場合もあるでしょう。

しかし、バックグラウンドでの位置情報取得はバッテリー消費が増加するリスクがあるため、適切な設定が必要です。

import android.app.PendingIntent
import android.content.Intent
import android.location.LocationManager

val intent = Intent(this, LocationReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

// バックグラウンドでの位置情報取得の設定
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 600000, 100f, pendingIntent)

このコードでは、PendingIntentを使用してバックグラウンドでの位置情報取得を行います。

位置情報が更新されると、LocationReceiverが呼び出され、その中で新しい位置情報を処理することができます。

○サンプルコード5:最後に取得された位置情報の取得

場面によっては、定期的な位置情報のアップデートを待たず、最後に取得された位置情報を直接利用したいことがあります。

例えば、アプリ起動時に直近の位置情報を表示したりする際に利用します。

この手法は、位置情報取得の頻度が必要ない場合やリアルタイムの更新を求めない場面で非常に効果的です。

Kotlinでの取得方法を見てみましょう。

import android.content.Context
import android.location.Location
import android.location.LocationManager

val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
val lastKnownLocation: Location? = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)

val latitude = lastKnownLocation?.latitude
val longitude = lastKnownLocation?.longitude

このコードではLocationManagergetLastKnownLocationメソッドを使用して、最後に取得された位置情報を取得しています。

特定のプロバイダ(この場合はGPS_PROVIDER)から取得した最新の位置情報が返されます。

このコードを実行すると、latitudeとlongitude変数にそれぞれの座標が格納され、これを基に地図上に位置を表示したり、他の操作を行うことができます。

しかし、この方法には一つ注意が必要です。

最後に取得された位置情報が古い、もしくは取得されていない場合、lastKnownLocationはnullとなる可能性があります。

そのため、nullチェックを適切に行い、位置情報がnullの場合の処理も記述することが必要です。

○サンプルコード6:特定の地域に入った際の通知

日常生活やビジネスの中で、特定の地域や場所に近づいた際に通知を受け取ることが便利なケースが多々あります。

例えば、ショッピングモールや観光地に近づいたときにクーポンや情報を受け取りたい場合などです。

このような機能を実現するためには、ジオフェンシングという技術を利用します。

import android.app.PendingIntent
import android.content.Intent
import android.location.Geofence
import android.location.GeofencingRequest
import android.location.LocationServices

val geofencingClient = LocationServices.getGeofencingClient(this)

// 通知を受け取る地域の中心点と半径を設定
val geofence = Geofence.Builder()
    .setRequestId("myGeofenceId")
    .setCircularRegion(35.6895, 139.6917, 500f) // 東京駅の周辺500m
    .setExpirationDuration(Geofence.NEVER_EXPIRE)
    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
    .build()

val geofencingRequest = GeofencingRequest.Builder()
    .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
    .addGeofence(geofence)
    .build()

val intent = Intent(this, GeofenceBroadcastReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

geofencingClient.addGeofences(geofencingRequest, pendingIntent)

このコードでは、東京駅の周辺500mをジオフェンスのエリアとして設定しています。

そして、このエリアに入った際にGeofenceBroadcastReceiverが呼び出されるようにしています。

このコードを実行すると、指定した地域に端末が入った時、指定したBroadcastReceiverが呼び出されます。

このReceiver内で、通知の表示やその他の操作を行うことができます。

○サンプルコード7:現在地の周辺情報の取得

アプリケーションを利用するユーザーが現在地の周辺のレストランや観光地、ショッピングモールなどの情報を取得したい場合があります。

このような機能を実装する際には、多くの場合Google Places APIなどのサービスを利用します。

今回はKotlinでの簡単な実装例を紹介します。

Google Places APIを利用するには、APIキーが必要となります。

公式サイトから取得できますので、事前に取得しておきましょう。

import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.api.net.PlacesClient
import com.google.android.libraries.places.api.net.PlacesSearchResponse

// APIキーの初期化
Places.initialize(applicationContext, "YOUR_API_KEY")
val placesClient: PlacesClient = Places.createClient(this)

// 現在地の座標を指定
val location = "35.6895,139.6917"  // 例: 東京駅
val resultType = Place.Type.RESTAURANT  // レストラン情報を取得

// 周辺情報の取得
val request = PlacesSearchResponse(location, 1000, resultType) // 1000m以内
val response = placesClient.fetchPlace(request)

このコードを利用することで、指定した位置の周辺1000m以内のレストラン情報を取得することができます。

取得された情報はresponseに格納され、これを利用してアプリ内で情報を表示したりすることができます。

このコードを実行すると、指定した地点の周辺のレストラン情報がリストとして取得され、それを基にマップ上にピンを立てたり、リスト表示することができます。

利用者にとって役立つ情報を簡単に取得し、提供することができます。

○サンプルコード8:地図上に現在地を表示

現在地の情報だけでなく、その位置情報を実際に地図上に表示することは、多くの位置情報を扱うアプリケーションで基本的な機能となります。

ここでは、KotlinとGoogle Maps SDK for Androidを利用して、地図上に現在地を表示する方法を解説します。

まず、Google Maps SDK for Androidを使用するための設定が必要です。

build.gradleに依存関係を追加し、APIキーも設定してください。

次に、簡単なコードを見てみましょう。

import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.model.LatLng

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

    private lateinit var mMap: GoogleMap

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)

        // 地図の初期化
        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        // 現在地を指定
        val location = LatLng(35.6895, 139.6917)  // 例: 東京駅
        mMap.addMarker(MarkerOptions().position(location).title("現在地"))
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 15.0f))
    }
}

このコードでは、現在地の位置情報をLatLngオブジェクトとして作成し、それを基に地図上にマーカーを立てています。

また、カメラの位置も現在地に移動させ、ズームレベルも適切に設定しています。

このコードを実行すると、指定した地点が地図上にマーカーとして表示され、その位置が中心となるように地図が表示されます。

○サンプルコード9:現在地の住所情報の取得

位置情報を取得するだけでなく、その位置情報を基に具体的な住所情報を取得する場面も多いでしょう。

例えば、天気予報アプリやフードデリバリーサービスなどでは、現在地の正確な住所を知る必要があります。

今回は、Kotlinで現在地の具体的な住所情報を取得する方法を詳しく解説します。

GoogleのGeocoding APIを利用することで、緯度と経度から具体的な住所情報を取得することができます。

まず、APIキーの取得が必要です。公式サイトからAPIキーを取得してください。

次に、実際のコードを見てみましょう。

import android.location.Geocoder
import java.util.Locale

// 現在地の緯度と経度を指定
val latitude = 35.6895
val longitude = 139.6917

val geocoder = Geocoder(this, Locale.getDefault())
val addresses = geocoder.getFromLocation(latitude, longitude, 1)

if (addresses.isNotEmpty()) {
    val address = addresses[0]
    val fullAddress = address.getAddressLine(0)
    println(fullAddress) // 例: "東京都千代田区丸の内1-9-1"
}

このコードを使って、緯度と経度を基に具体的な住所情報を取得することができます。

取得された住所情報はfullAddressに格納されています。

このコードを実行すると、指定した緯度と経度に基づく具体的な住所情報が出力されます。

例えば、上記のコードの場合は「東京都千代田区丸の内1-9-1」という住所情報が取得されます。

○サンプルコード10:現在地と指定された場所との距離計算

ユーザーの現在地と、指定された地点との間の距離を計算する場面も頻繁に見受けられます。

例えば、観光地やレストランの情報アプリで、ユーザーから「現在地からこのスポットまでの距離は?」といった問い合わせがあるかと思います。

ここでは、Kotlinを利用して、現在地と指定された地点との距離を計算する簡単なコード例を紹介します。

import android.location.Location

// 現在地の緯度と経度
val currentLocation = Location("current")
currentLocation.latitude = 35.6895
currentLocation.longitude = 139.6917

// 指定された地点の緯度と経度
val targetLocation = Location("target")
targetLocation.latitude = 35.6586
targetLocation.longitude = 139.7454

// 距離の計算
val distance = currentLocation.distanceTo(targetLocation)
println("距離:$distance m")

このコードを利用すると、現在地と指定された地点との間の距離をメートル単位で計算できます。

上記のコードの場合、出力される距離は約5.5kmとなります。

このコードを実行すると、指定した2点間の直線距離がメートル単位で計算され、その結果が出力されます。

●注意点と対処法

位置情報を取得する際には、多くのアプリケーション開発者や利用者が抱える問題や懸念事項が存在します。

特に、位置情報の精度やバッテリーの消費は、開発者にとって重要な要因となります。

ここでは、これらの問題に対する注意点と対処法を詳しく解説していきます。

○位置情報の精度に関する注意

位置情報の精度は、使用するデバイスや取得方法、周囲の環境によって大きく変動します。

例えば、都市部の高層ビルの中や地下では、GPSの受信が難しく、精度が低下することがあります。

このような場面で位置情報の精度を高める方法の一つとして、複数の位置情報源を組み合わせて使用する方法があります。

具体的には、GPSの他にWi-FiやBluetooth、加速度センサーなどを組み合わせて位置情報を取得することで、より高い精度での位置情報取得が期待できます。

○バッテリー消費に関する注意

位置情報を取得する際、バッテリー消費は無視できない問題点となります。

特に、GPSを常時使用する場合、バッテリー消費が著しく増える傾向にあります。

そのため、必要なタイミングや間隔でのみ位置情報を取得することで、バッテリーの消耗を抑えることが重要です。

□バッテリーの節約方法

バッテリーの節約を図るための方法として次のような対処法が考えられます。

  1. 位置情報の取得間隔を長くすることで、バッテリー消費を抑えることができます。
// 例: 10分ごとに位置情報を更新する
val locationRequest = LocationRequest.create().apply {
    interval = 600000  // 10分
    fastestInterval = 300000  // 5分
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

このコードを利用すると、位置情報の更新間隔が10分に設定され、最速で5分間隔での更新が可能となります。

バッテリーの消耗を抑えるために、位置情報の更新間隔を適切に設定することが求められます。

  1. 高い精度での位置情報取得はバッテリー消耗が大きいため、必要に応じて精度を下げて位置情報を取得することで、バッテリーの節約が期待できます。
val locationRequest = LocationRequest.create().apply {
    priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
}

このコードでは、バッテリー消耗を抑えつつ、適度な精度で位置情報を取得する設定となっています。

必要な精度に応じて適切に設定することで、効果的なバッテリー節約が期待できます。

●カスタマイズ方法

Kotlinを用いたAndroidアプリ開発において、現在地の取得は基本的な機能の一つです。

しかし、デフォルトの状態での位置情報取得だけでは、ユーザーのニーズを十分に満たすことは難しい場合があります。

ここでは、Kotlinでの位置情報取得をカスタマイズする方法を紹介します。

○位置情報の取得間隔のカスタマイズ

位置情報の取得間隔は、アプリケーションの性質やユーザーの利用状況に応じて最適化することが推奨されます。

たとえば、ナビゲーションアプリでは頻繁に位置情報を更新する必要がありますが、天気アプリのように位置情報が必要なタイミングが限られる場合は、取得間隔を長く設定することでバッテリーを節約できます。

// 位置情報の取得間隔を15分に設定
val locationRequest = LocationRequest.create().apply {
    interval = 900000  // 15分
    fastestInterval = 600000  // 10分
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

このコードを実行すると、15分ごとに位置情報を更新し、最速で10分の間隔で更新することができます。

取得間隔のカスタマイズは、アプリケーションの要件に応じて適切に設定することが求められます。

○表示される情報のカスタマイズ

位置情報を取得した際に、必要な情報だけを表示するカスタマイズも考えられます。

例えば、緯度や経度だけでなく、標高や速度、方向などの情報も取得できます。

これらの情報は、特定のアプリケーションでのみ必要とされるため、不要な情報を除外することで、ユーザー体験の向上やリソースの節約が期待できます。

// 緯度、経度、速度のみを取得
val location = ...
val latitude = location.latitude
val longitude = location.longitude
val speed = location.speed

上記のサンプルコードを実行すると、緯度、経度、速度の情報のみを取得することができます。

まとめ

Kotlinを使用してAndroidアプリケーションで現在地の取得を行うことは、多くの開発者にとって基本的なスキルとなっています。

この記事では、Kotlinを活用した現在地取得の基本から応用、さらにカスタマイズ方法までを徹底的に解説しました。

位置情報の取得は、ユーザー体験を大きく左右する要素の一つです。

そのため、適切な許可の取得、正確な位置情報の取得、そしてバッテリー消費の最小化など、多くの要因を考慮しながら開発を進めることが求められます。

Kotlinはその柔軟性と簡潔さから、初心者から上級者まで幅広い開発者に支持されています。

位置情報の取得も例外ではなく、Kotlinの機能をフルに活用することで、効率的かつ実用的な位置情報関連の機能をアプリケーションに組み込むことが可能です。

適切な許可の取得や情報の取扱いに十分注意し、ユーザーに安心してアプリを使用してもらうことを常に心掛けましょう。