안드로이드에서 국내외 지도앱의 길안내 연동을 위한 인텐트(Intent)를 정리했다. 참고로 공식적으로 문서화되지 않은 부분도 많이 있어서 한번 정리가 필요했다.

Problem

안드로이드에서 국내외 지도앱들의(문서화되지 않은 기능 포함) 길안내 연동 방법을 정리한다. 지도앱마다 지원하는 인텐트의 형식과 데이터가 다르고 공식적인 문서로 지원하지 않은 앱도 있어 모두 연동하기 위해서는 어려운점이 많았다.

Solution

네이버 지도

Intent(Intent.ACTION_VIEW, Uri.parse("navermaps://?menu=location&pinType=place&lat=$latitude&lng=$longitude&title=$title")).apply {
    `package` = "com.nhn.android.nmap"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

구글맵(Google Map)

Intent(Intent.ACTION_VIEW, Uri.parse("geo:$latitude,$longitude?q=$title")).apply {
    `package` = "com.google.android.apps.maps"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

티맵

티맵은 geo 스키마로 실행하면 제대로 동작하지 않았다. tmap 스키마로 패키지를 지정해서 실행하고 longitude, latitude를 추가로 전달한다.

티맵 (전용맵)

Intent(Intent.ACTION_VIEW, Uri.parse("tmap://route?goalx=$longitude&goaly=$latitude&goalname=$title")).apply {
    `package` = "com.skt.skaf.l001mtm091"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

티맵 (공용맵)

Intent(Intent.ACTION_VIEW, Uri.parse("tmap://route?goalx=$longitude&goaly=$latitude&goalname=$title")).apply {
    `package` = "com.skt.tmap.ku"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

원내비

원내비 (공용맵)

Intent(Intent.ACTION_VIEW, Uri.parse("geo:$latitude,$longitude?q=$title")).apply {
    `package` = "kt.navi"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

원내비 (LG유플러스 전용맵)

Intent(Intent.ACTION_VIEW, Uri.parse("geo:$latitude,$longitude?q=$title")).apply {
    `package` = "com.lguplus.navi"
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

카카오맵

implementation "com.kakao.sdk:kakaonavi:$kakaolib_version"
try {
    val builder = KakaoNaviParams.newBuilder(Location.newBuilder(
            title,
            longitude,
            latitude).build())
            .setNaviOptions(NaviOptions.newBuilder().setCoordType(CoordType.WGS84).build())

    KakaoNaviService.getInstance().navigate(context, builder.build())

} catch (e: Exception) {
    Notifications.alert(R.string.error_run_kakao_navi)
}

맵피

맵피는 위도, 경도를 통해서 해당 주소정보를 확인하는 과정을 먼저 수행한다. 해당 위치의 주소정보를 미리 알고 있을 경우 이 단계는 생략할 수 있다. 나의 경우에는 카카오 API를 이용해 coord2address.json를 호출하여 해당 위경도의 주소를 먼저 확인했다. 주소정보 확인 후 아래와 같이 맵피를 실행시킬 수 있다.

val packageName = "com.mnsoft.mappyobn"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=$address")).apply {
    `package` = packageName
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

try {
    context?.startActivity(intent)

} catch (e: Exception) {
    try {
        context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName")))
    } catch (e: ActivityNotFoundException) {
        context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName")))
    }
}

아틀란

예제 페이지의 coord2cipher.json를 이용하여 위도, 경로 좌표를 암호화하는 단계를 먼저 수행한다. 암호화가 완료된 후 아래와 같은 방식으로 앱을 실행할 수 있다.

val url = "intent://route/#Intent;scheme=linkatlan;package=kr.mappers.AtlanSmart;S.DestiShareType=sms;S.PoiCoordX=${result.x};S.PoiCoordY=${result.y};S.Poiname=${title};S.Poiid=;S.ButtonType=findroute;end"
val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
val packageName = "kr.mappers.AtlanSmart"

try {
    context?.startActivity(intent)

} catch (e: Exception) {
    try {
        context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName")))
    } catch (e: ActivityNotFoundException) {
        context?.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName")))
    }
}