複数の目的地のルートを確認する

このガイドに沿って、アプリ内で複数の目的地へのルートをプロットします。 ナビゲーション SDK for Android を使用します。

概要

  1. 次のように Navigation SDK をアプリに統合します。 (プロジェクトを設定するを参照)
  2. SupportNavigationFragment または アプリへの NavigationView。この UI 要素 は、インタラクティブな地図とターンバイターン方式のナビゲーション UI をアクティビティに追加します。
  3. NavigationApi クラスを使用して SDK を初期化します。
  4. ターンバイターン方式のナビゲーションを制御するために Navigator を定義します。

    • setDestinations() を使用してデスティネーションを追加します。
    • startGuidance() でナビを開始します。
    • getSimulator() を使用して、 テスト、デバッグ、デモンストレーションのために、 。
  5. アプリをビルドして実行します。

コードの確認

ナビゲーション フラグメントを追加する

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:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.navsdkmultidestination">
        <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.", DISPLAY_BOTH);
        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 ナビゲーションの使用を許可するものです。Navigator クラスにより、ナビゲーションの構成や開始/停止を制御できます。 取り組みます。

  1. 画面とログにメッセージを表示するヘルパー メソッドを作成します。

    private void displayMessage(String errorMessage, String displayMedium) {
        if (displayMedium.equals(DISPLAY_BOTH) || displayMedium.equals(DISPLAY_TOAST)) {
            Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
        }
    
        if (displayMedium.equals(DISPLAY_BOTH) || displayMedium.equals(DISPLAY_LOG)) {
            Log.d(TAG, errorMessage);
        }
    }
    
  2. Navigation SDK を初期化して、 ナビゲータの起動時にナビゲーションを開始する onNavigatorReady() コールバック ready:

    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.", DISPLAY_BOTH);
                    mNavigator = navigator;
                    mNavFragment = (SupportNavigationFragment) getFragmentManager()
                            .findFragmentById(R.id.navigation_fragment);
    
                    // Set the camera to follow the device location with 'TILTED' driving view.
                    mNavFragment.getCamera().followMyLocation(Camera.Perspective.TILTED);
    
                    // Navigate to the specified places.
                    navigateToPlaces();
                }
    
                /**
                 * 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.",
                                    DISPLAY_BOTH);
                            break;
                        case NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED:
                            displayMessage("Error loading Navigation SDK: User did not accept "
                                    + "the Navigation Terms of Use.", DISPLAY_BOTH);
                            break;
                        case NavigationApi.ErrorCode.NETWORK_ERROR:
                            displayMessage("Error loading Navigation SDK: Network error.",
                                    DISPLAY_BOTH);
                            break;
                        case NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING:
                            displayMessage("Error loading Navigation SDK: Location permission "
                                    + "is missing.", DISPLAY_BOTH);
                            break;
                        default:
                            displayMessage("Error loading Navigation SDK: " + errorCode,
                                    DISPLAY_BOTH);
                    }
                }
            });
    
  3. 特定の場所から Waypoint オブジェクトを作成するメソッドを追加します。 ID と役職です。

    private void createWaypoint(String placeId, String title) {
        try {
            mWaypoints.add(
              Waypoint.builder()
                     .setPlaceIdString(placeId)
                     .setTitle(title)
                     .build()
            );
        } catch (Waypoint.UnsupportedPlaceIdException e) {
            displayMessage("Error starting navigation: Place ID is not supported: " + placeId,
                    DISPLAY_BOTH);
        }
    }
    
  4. 各ルートまでの移動時間と距離を表示するメソッドを追加する あります

    private void displayTimesAndDistances() {
        List<TimeAndDistance> timesAndDistances = mNavigator.getTimeAndDistanceList();
        int leg = 1;
        String message = "You're on your way!";
        for (TimeAndDistance timeAndDistance : timesAndDistances) {
            message = message + "\nRoute leg: " + leg++
                    + ": Travel time (seconds): " + timeAndDistance.getSeconds()
                    + ". Distance (meters): " + timeAndDistance.getMeters();
        }
        displayMessage(message, DISPLAY_BOTH);
    }
    
  5. この行程のすべての地点を設定します。(エラー メッセージが返される場合があります) ナビゲータがルートをプロットできないプレイス ID を使用している場合サンプル オーストラリアの地点にプレイス ID を使用します。メモを見る 別のプレイス ID の取得については、下記をご覧ください)。計算後 ルートの場合、SupportNavigationFragment はポリラインを表示します。 地図上のルートを表し、各ウェイポイントにマーカーが配置されます。

    private void navigateToPlaces() {
    
        // Set up a waypoint for each place that we want to go to.
        createWaypoint("ChIJq6qq6jauEmsRJAf7FjrKnXI", "Sydney Star");
        createWaypoint("ChIJ3S-JXmauEmsRUcIaWtf4MzE", "Sydney Opera House");
        createWaypoint("ChIJLwgLFGmuEmsRzpDhHQuyyoU", "Sydney Conservatorium of Music");
    
        // If this journey is already in progress, no need to restart navigation.
        // This can happen when the user rotates the device, or sends the app to the background.
        if (mSavedInstanceState != null
                && mSavedInstanceState.containsKey(KEY_JOURNEY_IN_PROGRESS)
                && mSavedInstanceState.getInt(KEY_JOURNEY_IN_PROGRESS) == 1) {
            return;
        }
    
        // Create a future to await the result of the asynchronous navigator task.
        ListenableResultFuture<Navigator.RouteStatus> pendingRoute =
                mNavigator.setDestinations(mWaypoints);
    
        // 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:
                                mJourneyInProgress = true;
                                // Hide the toolbar to maximize the navigation UI.
                                if (getActionBar() != null) {
                                    getActionBar().hide();
                                }
    
                                // Register some listeners for navigation events.
                                registerNavigationListeners();
    
                                // Display the time and distance to each waypoint.
                                displayTimesAndDistances();
    
                                // 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.",
                                        DISPLAY_BOTH);
                                break;
                            case NETWORK_ERROR:
                                displayMessage("Error starting navigation: Network error.",
                                        DISPLAY_BOTH);
                                break;
                            case ROUTE_CANCELED:
                                displayMessage("Error starting navigation: Route canceled.",
                                        DISPLAY_BOTH);
                                break;
                            default:
                                displayMessage("Error starting navigation: "
                                        + String.valueOf(code), DISPLAY_BOTH);
                        }
                    }
                });
    }
    

アプリをビルドして実行する

  1. Android デバイスをコンピュータに接続します。手順に沿って、Android デバイスでデベロッパー オプションを有効にし、デバイスを検出するようにシステムを設定します(または、Android Virtual Device(AVD)Manager を使用して仮想デバイスを設定することもできます。エミュレータを指定する際は、必ず次の要素を含むイメージを選択してください。 説明します)。
  2. Android Studio で [Run] メニュー オプション(またはプレイボタン アイコン)をクリックします。表示される指示に沿ってデバイスを選択します。

ユーザー エクスペリエンスを向上させるためのヒント

  • ユーザーは、事前に Google ナビゲーション利用規約に同意する必要があります。 ナビゲーションが利用可能になりますこの同意が必要となるのは 1 回のみです。方法 デフォルトでは、ナビゲータを初めて起動したときに、 呼び出すことができます。必要に応じて、ナビゲーションの利用規約ダイアログを表示することもできます アプリの UX フローの初期段階(登録時やログイン時など)に、 showTermsAndConditionsDialog()
  • 以下を使用すると、ナビゲーションの品質と ETA の精度が大幅に向上します 緯度と経度ではなく、プレイス ID を使用して地点を初期化します。 あります。
  • このサンプルでは、特定の場所から地点を取得します あります。他にも、次のような方法でプレイス ID を取得できます。