단일 대상 경로 탐색

이 가이드에 따라 Android용 Navigation SDK를 사용하여 앱 내에 경로를 표시합니다. 이 가이드에서는 프로젝트 설정에 설명된 대로 Navigation SDK를 이미 앱에 통합했다고 가정합니다.

요약

  1. 탐색 프래그먼트 또는 탐색 뷰로 UI 요소를 앱에 추가합니다. 이 UI 요소는 활동에 대화형 지도 및 세부 경로 안내 내비게이션 UI를 추가합니다.
  2. 위치 정보 액세스 권한을 요청합니다. 기기의 위치를 확인하려면 앱에서 위치 정보 액세스 권한을 요청해야 합니다.
  3. NavigationApi 클래스를 사용하여 SDK를 초기화합니다.
  4. Navigator 클래스를 사용하여 목적지를 설정하고 세부 경로 안내 내비게이션을 제어합니다. 여기에는 다음 세 단계가 포함됩니다.

    • setDestination()를 사용하여 대상을 설정합니다.
    • startGuidance()로 내비게이션을 시작합니다.
    • getSimulator()를 사용하여 경로를 따라 차량의 진행 상황을 시뮬레이션하고 앱을 테스트 및 디버깅하고 시연합니다.
  5. 앱을 빌드하고 실행합니다.

코드 보기

앱에 UI 요소 추가

이 섹션에서는 세부 경로 안내 내비게이션을 표시하기 위한 대화형 지도와 UI를 추가할 수 있는 두 가지 방법을 설명합니다.

SupportNavigationFragment는 대화형 지도 및 세부 경로 안내를 포함하여 탐색의 시각적 출력을 표시하는 UI 구성요소입니다. 다음과 같이 XML 레이아웃 파일에서 프래그먼트를 선언할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.libraries.navigation.SupportNavigationFragment"
    android:id="@+id/navigation_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

또는 Android 문서에 설명된 대로 FragmentActivity.getSupportFragmentManager()를 사용하여 프래그먼트를 프로그래매틱 방식으로 구성할 수 있습니다.

프래그먼트의 대안으로, 탐색을 위해 지도를 표시하는 UI 구성요소를 NavigationView로도 사용할 수 있습니다.

위치 정보 액세스 권한 요청

이 섹션에서는 상세한 위치 정보 액세스 권한을 요청하는 방법을 설명합니다. 자세한 내용은 Android 권한 가이드를 참고하세요.

  1. Android 매니페스트에 권한을 <manifest> 요소의 하위 요소로 추가합니다.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.navsdksingledestination">
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    </manifest>
    
  2. 앱에서 런타임 권한을 요청하여 사용자에게 위치 정보 액세스 권한을 부여하거나 거부할 수 있는 기회를 제공합니다. 다음 코드는 사용자가 상세한 위치 정보 액세스 권한을 부여했는지 확인합니다. 부여하지 않은 경우, 해당 권한을 요청합니다.

    if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
            android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
        mLocationPermissionGranted = true;
    } else {
        ActivityCompat.requestPermissions(this,
                new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION },
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }
    
    if (!mLocationPermissionGranted) {
        displayMessage("Error loading Navigation SDK: "
                + "The user has not granted location permission.");
        return;
    }
    
  3. 권한 요청의 결과를 처리하도록 onRequestPermissionsResult() 콜백을 재정의합니다.

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                // If request is canceled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mLocationPermissionGranted = true;
                }
            }
        }
    }
    

Navigation SDK 초기화

NavigationApi 클래스는 앱에서 Google 탐색을 사용하도록 승인하는 초기화 로직을 제공합니다. 이 섹션에서는 탐색기를 초기화하는 방법과 앱에서 사용 설정할 수 있는 몇 가지 다른 구성을 설명합니다.

  1. Navigation SDK를 초기화하고 onNavigatorReady() 콜백을 재정의하여 탐색기가 준비되면 탐색을 시작합니다.

  2. 선택사항입니다. 사용자가 기기에서 앱을 닫을 때 안내 알림 및 백그라운드 서비스가 종료되도록 앱을 구성합니다. 선택은 비즈니스 모델에 따라 다릅니다. 앱이 닫혀도 회전 안내와 위치 업데이트가 계속 표시되는 기본 탐색기 동작을 사용하는 것이 좋습니다. 최종 사용자가 앱을 닫을 때 내비게이션 및 위치 업데이트를 종료하려면 이 구성을 사용합니다.

  3. 선택사항입니다. 지원되는 국가에서 도로 제한을 사용 설정하세요. 자동차 번호판의 마지막 숫자를 설정합니다. 이 호출은 한 번만 하면 됩니다. 이후 경로 요청에서 이 호출을 계속 사용합니다. 이 호출은 지원되는 리전에서만 작동합니다. Navigation SDK 지원 국가를 참고하세요.

    NavigationApi.getNavigator(this, new NavigationApi.NavigatorListener() {
                /**
                 * Sets up the navigation UI when the navigator is ready for use.
                 */
                @Override
                public void onNavigatorReady(Navigator navigator) {
                    displayMessage("Navigator ready.");
                    mNavigator = navigator;
                    mNavFragment = (NavigationFragment) getFragmentManager()
                            .findFragmentById(R.id.navigation_fragment);
    
                    // Optional. Disable the guidance notifications and shut down the app
                    // and background service when the user closes the app.
                    // mNavigator.setTaskRemovedBehavior(Navigator.TaskRemovedBehavior.QUIT_SERVICE)
    
                    // Optional. Set the last digit of the car's license plate to get
                    // route restrictions for supported countries.
                    // mNavigator.setLicensePlateRestrictionInfo(getLastDigit(), "BZ");
    
                    // Set the camera to follow the device location with 'TILTED' driving view.
                    mNavFragment.getCamera().followMyLocation(Camera.Perspective.TILTED);
    
                    // Set the travel mode (DRIVING, WALKING, CYCLING, TWO_WHEELER, or TAXI).
                    mRoutingOptions = new RoutingOptions();
                    mRoutingOptions.travelMode(RoutingOptions.TravelMode.DRIVING);
    
                    // Navigate to a place, specified by Place ID.
                    navigateToPlace(SYDNEY_OPERA_HOUSE, mRoutingOptions);
                }
    
                /**
                 * Handles errors from the Navigation SDK.
                 * @param errorCode The error code returned by the navigator.
                 */
                @Override
                public void onError(@NavigationApi.ErrorCode int errorCode) {
                    switch (errorCode) {
                        case NavigationApi.ErrorCode.NOT_AUTHORIZED:
                            displayMessage("Error loading Navigation SDK: Your API key is "
                                    + "invalid or not authorized to use the Navigation SDK.");
                            break;
                        case NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED:
                            displayMessage("Error loading Navigation SDK: User did not accept "
                                    + "the Navigation Terms of Use.");
                            break;
                        case NavigationApi.ErrorCode.NETWORK_ERROR:
                            displayMessage("Error loading Navigation SDK: Network error.");
                            break;
                        case NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING:
                            displayMessage("Error loading Navigation SDK: Location permission "
                                    + "is missing.");
                            break;
                        default:
                            displayMessage("Error loading Navigation SDK: " + errorCode);
                    }
                }
            });
    

대상 설정

Navigator 클래스는 탐색 여정의 구성, 시작, 중지를 제어할 수 있습니다.

이전 섹션에서 가져온 Navigator를 사용하여 이 여정의 대상 Waypoint를 설정합니다. 경로를 계산한 후 SupportNavigationFragment는 지도에 경로를 나타내는 다중선과 목적지에 마커를 표시합니다.

    private void navigateToPlace(String placeId, RoutingOptions travelMode) {
        Waypoint destination;
        try {
            destination = Waypoint.builder().setPlaceIdString(placeId).build();
        } catch (Waypoint.UnsupportedPlaceIdException e) {
            displayMessage("Error starting navigation: Place ID is not supported.");
            return;
        }

        // Create a future to await the result of the asynchronous navigator task.
        ListenableResultFuture<Navigator.RouteStatus> pendingRoute =
                mNavigator.setDestination(destination, travelMode);

        // Define the action to perform when the SDK has determined the route.
        pendingRoute.setOnResultListener(
                new ListenableResultFuture.OnResultListener<Navigator.RouteStatus>() {
                    @Override
                    public void onResult(Navigator.RouteStatus code) {
                        switch (code) {
                            case OK:
                                // Hide the toolbar to maximize the navigation UI.
                                if (getActionBar() != null) {
                                    getActionBar().hide();
                                }

                                // Enable voice audio guidance (through the device speaker).
                                mNavigator.setAudioGuidance(
                                        Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE);

                                // Simulate vehicle progress along the route for demo/debug builds.
                                if (BuildConfig.DEBUG) {
                                    mNavigator.getSimulator().simulateLocationsAlongExistingRoute(
                                            new SimulationOptions().speedMultiplier(5));
                                }

                                // Start turn-by-turn guidance along the current route.
                                mNavigator.startGuidance();
                                break;
                            // Handle error conditions returned by the navigator.
                            case NO_ROUTE_FOUND:
                                displayMessage("Error starting navigation: No route found.");
                                break;
                            case NETWORK_ERROR:
                                displayMessage("Error starting navigation: Network error.");
                                break;
                            case ROUTE_CANCELED:
                                displayMessage("Error starting navigation: Route canceled.");
                                break;
                            default:
                                displayMessage("Error starting navigation: "
                                        + String.valueOf(code));
                        }
                    }
                });
    }

앱 빌드 및 실행하기

  1. 컴퓨터에 Android 기기를 연결합니다. Android 스튜디오의 하드웨어 기기에서 앱을 실행하는 방법에 관한 안내를 따르세요. 또는 Android Virtual Device (AVD) Manager를 사용하여 가상 기기를 구성할 수 있습니다. 에뮬레이터를 선택할 때 Google API가 포함된 이미지를 선택해야 합니다.
  2. Android 스튜디오에서 Run 메뉴 옵션 또는 재생 버튼 아이콘을 클릭합니다. 표시되는 메시지에 따라 기기를 선택합니다.

사용자 환경 개선을 위한 힌트

  • 내비게이션을 사용하려면 사용자가 Google 내비게이션 서비스 약관에 동의해야 합니다. 승인은 한 번만 수행하면 됩니다. 기본적으로 SDK는 탐색기를 처음 호출할 때 수락 여부를 묻는 메시지를 표시합니다. 원하는 경우 앱 UX 흐름의 초기 지점(예: 가입 또는 로그인 단계)에서 TermsAndConditionsCheckOption를 사용하여 탐색 서비스 약관 대화상자를 트리거할 수 있습니다.
  • 탐색 품질 및 ETA 정확성을 크게 개선하려면 장소 ID를 사용하여 위도/경도 좌표가 아닌 경유지를 초기화하세요.
  • 이 샘플은 시드니 오페라 하우스의 특정 장소 ID에서 목적지 경유지를 가져옵니다. 장소 ID 파인더를 사용하여 다른 특정 위치의 장소 ID를 가져올 수 있습니다.