ハッカソンで、OSMつかって経路出したいねーなんてメンバーと話をしていて、その為にちょっとやってみたのでメモついでにまとめておく。
#参考にした記事
参考にした Androidで道案内アプリケーションを作る はJavaだったので、Kotlinで書きながら実装してみた。
実際の実装は参照元を参考してもらうとして、実際にこの記事でつまづいたことなどを補足していきます。
参考にした記事を投稿してくれた方には感謝!
- OSMBounusPackの導入
- NavigationActivity.javaのコードはMainActivity.java(MainActivity.kt)で実装
- HTTP通信の許可が必要
- MapEventsReceiverのsingleTapConfirmedHelperメソッドで NetworkOnMainThreadException
##OSMBounusPackの導入
これ、オフィシャルのドキュメントを見ても、ハマる人はハマります。
プロジェクトのbuild.gradleとappのbuild.gradleを変更する必要があります。
また、このライブラリを追加しないと、経路検索ができません。
まず、プロジェクトのbuild.gradleに以下のように maven { url "https://jitpack.io" } を追加します。
buildscriptの方ではなく、allprojectsの方に追加してください。
知ってればなんてことないと思いますが、知らなくて、ちょっと悩みました。
allprojects {
repositories {
google()
jcenter()
//OSMDroid Bonus Packを利用するための準備
maven { url "https://jitpack.io" }
}
}
次にappのbuild.gradleに implementation 'com.github.MKergall:osmbonuspack:6.6.0' を追加します。
追加するOSMBounusPackのバージョンはオフィシャルのGitを参照すると良いと思います。
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.osmdroid:osmdroid-android:6.1.8'
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.github.MKergall:osmbonuspack:6.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
##MapEventsReceiverのsingleTapConfirmedHelperメソッドの実装時の注意点
以下の処理で NetworkOnMainThreadException が発生しました。
road = roadManager.getRoad(waypoints)
そのため、コルーチンを使って回避しました
override fun singleTapConfirmedHelper(p: GeoPoint?): Boolean {
targetLat = p!!.latitude
targetLng = p!!.longitude
if(waypoints.size > 0){
waypoints.clear()
}
var startPoint = GeoPoint(lat, lng)
var endPoint = GeoPoint(targetLat, targetLng)
waypoints.add(startPoint)
waypoints.add(endPoint)
// NetworkOnMainThreadException を回避する
GlobalScope.launch(Dispatchers.IO) {
var mapView = findViewById<MapView>(R.id.mapView)
// 経路の取得
road = roadManager.getRoad(waypoints)
##HTTP通信の許可が必要
ざっくりと対応する場合は、AndroidManifest.xmlのApplicationタグにandroid:usesCleartextTraffic="true"追加して対応しちゃいましょう。
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.OSMSample"
android:usesCleartextTraffic="true">
最後に
経路検索が結構早くて驚きました。
参考サイトをベースに改造して利用したり、ほかの実行もしたので、その辺は別の記事で投稿したいと思います。