[Flutter] 우당탕탕 개발 일지5 - 내비게이션 앱 실행하기

Leona·2023년 10월 11일
0
post-thumbnail

Flutter에서 외부 앱을 실행하려면 url scheme으로 호출하면 된다.
근데 iOS는 url 쿼리로 출발, 도착지 설정되는데 안드로이드는 설정되지 않아서 애 먹다가 결국 tmap api 고객센터에 문의를 남겼다. 생각보다 답변이 빨리 와서 놀랐다. 게다가 친절하게 예제 코드라던지 참조할만한 것들을 알려주셔서 기분이 좋았다. skt 최고!(정작 본인 유플러스 이용중 ㅋㅋ;;ㅎㅎ..ㅈㅅ..!!)

내비게이션 앱 실행하기

프로젝트 진행중 선택한 위치로 길을 찾기 위해 내비게이션 앱을 실행해야 하는 기능이 있었다.
카카오 내비, 네이버 지도, 티맵을 각각 실행해야 했다. 다들 친절하게 API 문서가 있어서 무탈하게 실행하는 것 까지 구현했다. 현재 기기에 앱이 설치되어 있지 않다면 OS별 스토어 페이지로 이동하고, 설치되어 있다면 앱을 실행하도록 했다. 스토어 주소는 웹에서 따왔다.

티맵

  • iOS는 'tmap://route?rGoName=도착지이름&rGoX=경도&rGoY=위도'만 입력해도 출발지는 현재 위치, 도착지는 쿼리로 전송한 이름과 위경도로 설정된다.
  • 안드로이드도 iOS와 동일한 url로 실행했으나 도착지 설정이 안되는 문제가 생겼다. 구글링해도 안나오고 gpt도 모르길래 문의를 남겼다. 답변대로 했더니 잘 돌아갔다.
    • AndroidManifest 파일에 package를 두개 추가하고, 쿼리도 이렇게 쓰면 된다고 친절하게 알려주셨다. 정말 감사합니다.
      'tmap://route?referrer=com.skt.Tmap&goalx=경도&goaly=위도&goalname=도착지이름'
// tmap
IconButton(
	...
    onPressed: () async {
    	var url = Platform.isIOS
					? 'tmap://route?rGoName=${Uri.encodeComponent(name)}&rGoX=$lng&rGoY=$lat'
					: 'tmap://route?referrer=com.skt.Tmap&goalx=$lng&goaly=$lat&goalname=$name';

		if (await canLaunchUrl(Uri.parse(url))) {
        	await launchUrl(Uri.parse(url));
        } else {
			var store = Platform.isIOS
							? 'https://apps.apple.com/app/id431589174'
							: 'https://play.google.com/store/apps/details?id=com.skt.tmap.ku&hl=ko-KR';

			launchBrowserTab(Uri.parse(store));
		}

		return;
	},
    ...
),
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET"/> <!-- 인터넷 권한 -->

<queries>
  ...
  <package android:name="com.skt.skaf.l001mtm091" /> <!-- <- 이 패키지 하나만 더 추가하면 된다..! -->
  <package android:name="com.skt.tmap.ku" />
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:host="com.skt.tmap.ku" android:scheme="tmap" />
  </intent>
  ...
</queries>

카카오 내비

  • kakao_flutter_sdk, kakao_flutter_sdk_navi 플러그인 설치 후 메소드를 사용할 수 있다.
  • navigate() 메소드에 coordinate type을 wgs84로 지정해주어야 올바른 위치로 길안내를 시작한다.
// 카카오 내비
IconButton(
	...
	onPressed: () async {
		bool result = await NaviApi.instance.isKakaoNaviInstalled();

		if (result) {
			await NaviApi.instance.navigate(
					destination: Location(
                      name: name,
                      x: lng.toString(),
                      y: lat.toString()),
                      // 이 옵션이 있어야 정상적으로 내비 작동함
                      option: NaviOption(coordType: CoordType.wgs84),
					);
		} else {
			// 카카오내비 설치 페이지로 이동
			await launchBrowserTab(Uri.parse(NaviApi.webNaviInstall));
		}
	},
	...
),
<!-- AndroidManifest.xml -->
<application>
  ...
  <activity>
    ...
    <intent-filter>
      <data android:host="kakaonavi" android:scheme="kakao네이티브앱키" /> <!-- kakao + 네이티브 앱 키를 조합해서 넣어야 함 -->
    </intent-filter>
    ...
  </activity>
  ...
  <meta-data
     android:name="com.kakao.sdk.AppKey"
     android:value="네이티브앱키" />
</application>

네이버 지도

  • url scheme 쿼리에 appname=앱번들네임을 넣어야 한다.
// 네이버 지도
IconButton(
	...
	onPressed: () async {
		var url = 'nmap://navigation?dlat=$lat&dlng=$lng&dname=$name&appname=com.example.appname';

		if (await canLaunchUrl(Uri.parse(url))) {
			await launchUrl(Uri.parse(url));
		} else {
			var store = Platform.isIOS
							? 'https://apps.apple.com/kr/app/naver-map-navigation/id311867728'
                            : 'https://play.google.com/store/apps/details?id=com.nhn.android.nmap&hl=ko-KR';

			await launchBrowserTab(Uri.parse(store));
		}
	},
	...
),
<!-- AndroidManifest.xml -->
<queries>
  ...
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="nmap" />
  </intent>
  ...
</queries>

실행화면을 캡쳐하고 싶은데 현재 데이터가 없어서 할 수가 없다... 나중에 추가하도록 하겠다.
profile
레오나의 기묘한 개발 일지

1개의 댓글

comment-user-thumbnail
2024년 8월 15일

안녕하세요! 좋은 글 잘 봤습니다~

답글 달기