mcpField
M
migrating-navsdk-7x-to-8x-android

migrating-navsdk-7x-to-8x-android

github.com/googlemaps開発7014 回インストール2 日前に更新
リポジトリ

migrating-navsdk-7x-to-8x-android について

Navigation SDKを7.xから8.0へ移行するAndroid開発者向けのスキルです。ツールチェーン、依存関係、破壊的変更、非推奨APIを段階的に確認でき、コードを変更しない監査にも対応します。

主な機能

  1. 01移行前の環境とコードの棚卸し
  2. 02段階的なツールチェーンと依存関係の更新
  3. 03必須となるAPI変更の特定
  4. 04代替案付きの非推奨項目一覧
  5. 05編集を行わない監査結果の報告

活用シーン

  1. 01AndroidアプリをNavSDK 7.xから8.0へ更新
  2. 02更新前にAGP、Gradle、JDK要件を確認
  3. 03ビルドや動作に影響するAPI変更を特定
  4. 04コードを変更せず移行作業を評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/googlemaps/agent-skills --skill migrating-navsdk-7x-to-8x-android

インストール後、Claude Code で/migrating-navsdk-7x-to-8x-androidを入力して読み込まれたか確認します。

同梱ファイルreferences/toolchain_bump.md

詳細

Navigation SDK for Android 7.x から 8.0 への移行

まずお読みください:変更されない点

これは同じ SDK のバージョンアップです。パッケージ名を変更したり、アーティファクトを差し替えたり、ナビゲーターの初期化方法を変更したりしないでください。

  • パッケージ名前空間は com.google.android.libraries.navigation.* のままです。 インポートを書き換えないでください。
  • アーティファクトは com.google.android.libraries.navigation:navigation のままです。 変更するのはバージョンのみです。
  • 初期化方法は変わりません。 これまでどおり NavigationApi.getNavigator(...) を呼び出してください。
  • Navigator.RouteStatus は引き続き Java の enum です。 int 定数に変換しないでください。

ワークフロー

次の順番で作業してください。ツールチェーンが正しく設定されるまで 8.0 ではコンパイルできません。また、設定できないビルドに対して呼び出し箇所を修正しても、作業をやり直すことになります。削除されたシンボルはコンパイルできませんが、非推奨のシンボルは警告が出るだけなので、非推奨化より先に重大な破壊的変更に対応してください。フェーズ 4 は開発者が判断するスケジュール上の選択肢であり、必須ではありません。

フェーズ 0:事前確認

変更を加える前に、以下を記録してください。以降のフェーズはこれらの情報に応じて分岐します。

  • 現在の NavSDK バージョン (com.google.android.libraries.navigation:navigation:<version>)。このガイドの対象は 7.x から 8.0 への移行のみです。アプリが 6.x 以前の場合は、まず リリースノートに従って最新の 7.x にアップグレードし、ビルドが成功することを確認してから、ここに進んでください。
  • ビルド DSL(Groovy の build.gradle または Kotlin の build.gradle.kts)、AGP と Gradle のバージョン、Gradle を実行している JDK。
  • ソース言語(Java、Kotlin、または両方)。
  • レイアウト XML で NavSDK フラグメントを参照しているかどうか、およびアプリが Android Auto(androidx.car.app)を使用しているかどうか。
  • ユーザーの目的:完全な移行、「ビルドを通す」だけの対応、または監査のみ。監査の場合は、フェーズ 1~4 の検出結果を報告し、変更は加えないでください。

影響を受けるシンボルを一度に洗い出してください。この結果が以降の移行作業のリストになります。各該当箇所は以下のフェーズ 1~4 の項目に対応し、監査ではフェーズごとにまとめて報告します。レイアウト XML も検索してください。XML 内のフラグメントクラス名は、インフレート時までエラーにならないためです。Kotlin のコードでは通常、後続の型が推論されます(val pending = navigator.setDestination(...) など)。そのため、ListenableResultFuture だけを検索しても見つかりませんが、setOnResultListener なら検出できます。

以下のシンボルを Java、Kotlin、XML、Gradle、ProGuard のファイルで検索してください。シェルを使えない場合は、環境のコード検索機能を使ってください。シェルが使える場合は、次のコマンドで検索できます。

grep -rnE "showTrafficLights|showStopSigns|onGpsAvailabilityUpdate|ListenableResultFuture|setOnResultListener|SupportNavigationFragment|setAudioGuidance\(|simulateLocationsAlongNewRoute|MAP_TYPE_TERRAIN|RouteStatus|getNavigator|NavigationTransactionRecorder|FollowMyLocationOptions|header[A-Za-z]*(TypefacePath|TextSize)|kotlin-reflect|kotlin\.reflect|bumptech\.glide|androidx\.car\.app" \
  --include=*.java --include=*.kt --include=*.xml --include=*.gradle --include=*.kts --include=*.pro .
フェーズ 1:ツールチェーン

8.0 の AAR メタデータでは、minAndroidGradlePluginVersion=9.0.1 が宣言されています。AGP 8.x では、Gradle はビルドの設定を拒否します。非推奨の警告は表示されず、ハードエラーになります。まずこれを修正してください。

プロジェクトがすでに AGP >= 9.0.1 かつ compileSdk 37 の場合、フェーズ 1 は確認のみです。Gradle ラッパーがその AGP バージョンの要件を満たし、JDK が 17/21 であることを確認したら、次に進んでください。より新しい AGP を 9.0.1 にダウングレードしないでください。

NavSDK 7.x は AGP 9.0.1 / Gradle 9.1.0 / compileSdk 37 で問題なくビルドできます(公開済みの 7.9.0 サンプルアプリで確認済み)。NavSDK のバージョンを変更する前に、7.x のままツールチェーンを更新し、デバッグとリリースのビルドを成功させてください。そうすれば、それ以降に発生する問題はすべて、AGP ではなく NavSDK に起因すると判断できます。

  • Android Gradle プラグイン:8.13.2 から 9.0.1。最低要件です(AAR メタデータ)。
  • Gradle:8.13 から 9.1.0(AGP 9.0.1 用)。より新しい AGP 9.x には、より新しい Gradle が必要です(例:AGP 9.2.0 には Gradle 9.4.1)。AGP のエラーメッセージに従ってください。
  • compileSdk / targetSdk:36 から 37。SDK ターゲットは 37 です。
  • Kotlin:2.3.0 から 2.3.0。変更なし。
  • desugar_jdk_libs_nio:2.0.x から 2.1.5。AAR メタデータによって必須です。
  • com.google.gms:google-services:4.4.x から 4.5.0。使用している場合のみ(AGP 9 では applicationVariants が削除されました)。

AGP 9.0.1 は compileSdk 37 に対して、「This Android Gradle plugin (9.0.1) was tested up to compile SDK version 36.1」と表示します。この警告は想定内で、問題ありません。表示を抑制するには、gradle.properties に android.suppressUnsupportedCompileSdk=37.0 を追加してください(または、より新しい AGP 9.x を使用してください)。

注意

開発者に JDK 25 が必要だと伝えないでください。JDK 25 は NavSDK 自体のビルドに使用する内部ツールチェーンです。AGP 9 を使用するホストアプリでは、Gradle の実行に必要な JDK の最低バージョンは 17 で、JDK 21 LTS が推奨されます。

AGP 9 自体が動作を変更するため、NavSDK との関連が明らかでないビルドエラー(例:マニフェスト内の package=、kotlinOptions、dexOptions)が発生することがあります。症状と修正方法の一覧は、references/toolchain_bump.md を参照してください。内容を言い換えず、公式の AGP 9.0 リリースノート にリンクしてください。org.jetbrains.kotlin.multiplatform と Android プラグインを組み合わせる Kotlin Multiplatform モジュールでは、モジュール構成の変更に関して JetBrains の AGP 9 移行ガイド(kotlin-tooling-agp9-migration スキル)に従い、NavSDK の上記の最低要件も引き続き適用してください。

targetSdk 37 には、コード変更ではなく Play Console 上の対応が必要です。 NavSDK を使用するアプリは、Google Play Console で位置情報の利用目的の申告を完了する必要があります。ナビゲーション中に高精度位置情報(ACCESS_FINE_LOCATION)を継続的に使用する理由を示すため、ナビゲーションを選択し、ナビゲーション以外の用途も申告してください。ユーザーに伝えてください。これはコードからは実行できません。Play Console の位置情報申告ガイドを参照してください。

フェーズ 2:依存関係

8.0 では、いくつかの推移的依存関係が取り込まれなくなりました。サイズ削減の程度はアプリによって異なります。すでにこれらを削除していなかったアプリでは最大約 4.8 MB、R8(たとえばフルモード)ですでに縮小しているアプリでは、削減幅は大幅に小さくなります。

  • org.jetbrains.kotlin:kotlin-reflect
  • com.github.bumptech.glide:glide および com.github.bumptech.glide:okhttp3-integration

アプリ独自のコードで参照している場合に限り、どちらか一方を再度追加してください。対象となるのは、::class/KClass の基本機能を超える kotlin.reflect.* API、または com.bumptech.glide.* のインポートです。無条件に再追加すると、NavSDK が今回実現したサイズ削減が失われます。更新後にこれらのパッケージで「クラスが見つからない」エラーが発生した場合は、再追加が必要なサインです。

逆に、アプリで kotlin-reflect または Glide を明示的に宣言していても(NavSDK の推移的依存関係を反映するため、何年も前にコピーされていることがよくあります)、アプリ独自のコードや ProGuard ルールに kotlin.reflect.*/com.bumptech.glide.* の使用がない場合は、その宣言(および対応する annotationProcessor/kapt/ksp エントリー)を削除して、サイズ削減を実現してください。

Android Auto: 8.0 では、androidx.car.app 用の ProGuard keep ルールが同梱されなくなりました。Android Auto の投影モードを使用するアプリでは、androidx.car.app:app と androidx.car.app:app-projected を 1.3.0 以降にアップグレードし、各ライブラリ独自のコンシューマールールが適用されるようにしてください。そうしないと、デバッグビルドでは引き続き動作する一方、リリース(R8)ビルドでは必要なクラスが削除される可能性があります。

NavSDK が更新したその他のライブラリバージョン(AndroidX lifecycle 2.10.0、material 1.14.0、datastore 1.2.1、window 1.5.1、transport 4.1.1 など)は、Gradle によって自動的に解決されます。アプリで古いバージョンを固定していて、依存関係の解決に失敗する場合にのみ対応してください。

フェーズ 3:重大な変更(コンパイルまたは正しい動作のために修正が必要)
  • DisplayOptions.showTrafficLights(...)、showStopSigns(...):削除されました。 呼び出しを削除してください。データが利用可能な国では、ナビゲーション中に信号機と一時停止標識が常に表示されるようになりました。
  • RoadSnappedLocationProvider.GpsAvailabilityEnhancedLocationListener.onGpsAvailabilityUpdate(boolean): 削除されました。 オーバーライドを削除し、ロジックを onGpsAvailabilityChange(GpsAvailabilityChangeEvent) に移してください。オーバーライドが残っていると、コンパイルに失敗します。
  • Navigator.RouteStatus.ROUTING_TIMEOUT:新しい enum 定数です。ルーティングバックエンドがタイムアウトしたことを示します。 アプリがすべてのステータスを処理する箇所(下記を参照)に分岐を追加してください。
  • ナビゲーション中の GoogleMap.MAP_TYPE_TERRAIN:サポートされなくなりました。 コンパイルは問題なく通りますが、実行時にはナビゲーションが終了するまで、地図が MAP_TYPE_NORMAL に戻ります。ユーザーに適用されないモードが表示されないよう、ナビゲーション中の UI から地形図オプションを削除してください。
  • StylingOptions の Parcelable メンバー(CREATOR、writeToParcel): 内部実装であり、公開 API の一部ではありません。 StylingOptions を(Bundle/Intent の extras などを介して)Parcelable として扱わないでください。必要な場所でビルダーメソッドから再構築してください。
  • getNavigator(Application, ...) からの NavigationApi.ErrorCode.NETWORK_ERROR:動作が変更され、発生する場合があります。 7.x では報告されることはありませんでした。8.0 では、ネットワークエラーまたはタイムアウトエラーで利用規約の確認に失敗し、Activity がない場合(Application オーバーロード)、以前は TERMS_NOT_ACCEPTED が返されていたところで、onError に NETWORK_ERROR が渡されます。onError に NETWORK_ERROR の分岐がない場合は、利用規約を再度表示したり致命的なエラーとして扱ったりするのではなく、(バックオフを伴う)getNavigator の再試行を行う分岐を追加してください。既存の NETWORK_ERROR 処理は維持してください。

ROUTING_TIMEOUT と網羅性。 この定数は追加ですが、網羅的な処理が必須のコードでは問題が発生します。

  • 式として使う Kotlin の when (status) は、ROUTING_TIMEOUT を網羅するか else を設けるまでコンパイルできません。
  • enum を対象とする Java の switch 式(値を返す -> 形式)もコンパイルエラーになります。
  • 通常の Java switch 文はコンパイルできますが、新しいステータスは何も処理されないまま見落とされます。タイムアウト時にユーザーに表示される処理(通常は「再試行」)が行われるよう、case を追加してください。
val message = when (routeStatus) {
    Navigator.RouteStatus.OK -> null
    Navigator.RouteStatus.ROUTING_TIMEOUT -> "Route calculation timed out. Try again."
    Navigator.RouteStatus.NETWORK_ERROR -> "Network error. Check your connection."
    // ...existing branches...
    else -> "Could not calculate a route ($routeStatus)."
}
フェーズ 4:非推奨項目(8.0 では警告付きでコンパイルされます。今すぐ修正するか、対応を予定してください)

ユーザーに選択肢として提示してください。全面的な移行を依頼されていない限り、すべての呼び出し箇所を黙って書き換えないでください。それぞれについて、使用箇所と削除時期を報告してください。全面的な移行を依頼された場合、または非対話モードで実行している場合は、置き換え先がある非推奨項目をすべて移行し、置き換え先がない項目(StylingOptions の書体/文字サイズ、およびアプリで独自オプションが必要な場合の FollowMyLocationOptions)は保留として一覧にしてください。

  • Navigator.setDestination(s)(...) が返す ListenableResultFuture<RouteStatus>:末尾に RouteDescriptionLoadCallback を取って void を返すオーバーロードに置き換えます。削除時期:9.0。
  • ListenableResultFuture を返す Simulator.simulateLocationsAlongNewRoute(...):末尾に RouteDescriptionLoadCallback を取るオーバーロードに置き換えます。削除時期:9.0。
  • SupportNavigationFragment:NavigationFragment に置き換えます(同じパッケージ、同じメソッド、newInstance()/newInstance(GoogleMapOptions))。削除時期:9.0。
  • NavigationTransactionRecorder.pickup(Waypoint, List)/dropoff(Waypoint, List):pickup(List)/dropoff(List) に置き換えます。削除時期:9.0。
  • Navigator.setAudioGuidance(@AudioGuidance int):setAudioGuidanceSettings(AudioGuidanceSettings) に置き換えます。削除時期:8.0 の約 1 年後。
  • StylingOptions の書体パスおよび文字サイズのメソッド(header*TypefacePath、header*TextSize とゲッター):置き換え先はありません。色のオプションは引き続き使用できます。削除時期:未発表。
  • GoogleMap.followMyLocation(int, FollowMyLocationOptions) および FollowMyLocationOptions クラス(com.google.android.gms.maps.model):直接の置き換え先はありません。アプリで独自オプション(ズームレベルなど)が不要な場合は、同じ視点で followMyLocation(int) を呼び出してください。このオーバーロードは非推奨ではありません。それ以外の場合は呼び出しを維持し、保留として報告してください。削除時期:将来のリリース(未発表)。
ListenableResultFuture から RouteDescriptionLoadCallback へ

RouteDescriptionLoadCallback はトップレベルインターフェース com.google.android.libraries.navigation.RouteDescriptionLoadCallback で、単一メソッド onRouteDescription(RouteDescription) を持ち、UI スレッドで呼び出されます。 RouteDescription.getRouteStatus() は Navigator.RouteStatus の列挙型を返します。

// Before (deprecated in 8.0)
ListenableResultFuture<Navigator.RouteStatus> future = navigator.setDestination(waypoint);
future.setOnResultListener(status -> {
  if (status == Navigator.RouteStatus.OK) {
    navigator.startGuidance();
  }
});

// After
navigator.setDestination(
    waypoint,
    routeDescription -> {
      if (routeDescription.getRouteStatus() == Navigator.RouteStatus.OK) {
        navigator.startGuidance();
      }
    });
navigator.setDestination(waypoint) { routeDescription ->
    if (routeDescription.routeStatus == Navigator.RouteStatus.OK) {
        navigator.startGuidance()
    }
}

RoutingOptions、DisplayOptions、CustomRoutesOptions を使用する各 setDestination/setDestinations オーバーロードには、先頭のパラメーターが同じコールバック対応版があります。

SupportNavigationFragment から NavigationFragment へ

コードとレイアウト XML の両方でクラスを置き換え、<fragment>/FragmentContainerView の android:name="..." 属性と class="..." 属性の両方を対象にしてください。コードのみを置き換えると、コンパイルは正常に完了しますが、インフレーション時にクラッシュするか、XML 内で非推奨クラスが使われ続けます。

<fragment
    android:id="@+id/navigation_fragment"
    android:name="com.google.android.libraries.navigation.NavigationFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

NavigationFragment は SupportNavigationFragment と同様に AndroidX の Fragment であるため、supportFragmentManager の使用方法に変更はありません。インポートだけでなく、すべての参照を更新してください。フィールド/プロパティの型、(SupportNavigationFragment) getSupportFragmentManager().findFragmentById(...) のようなキャスト、instanceof/Kotlin の is チェック、SupportNavigationFragment() コンストラクターの呼び出し、SupportNavigationFragment.newInstance(...) の呼び出し、KDoc/Javadoc の [SupportNavigationFragment] リンクが対象です。 NavigationFragment への更新を参照してください。

setAudioGuidance(int) から setAudioGuidanceSettings(...) へ

デフォルト値は逆になっています。以前のフラグのビットマスクはゼロから値を加算していましたが、AudioGuidanceSettings.builder() は振動がオン、GuidanceMode.VOICE_ALERTS_AND_GUIDANCE、Bluetooth オーディオがオン、VolumeLevel.NORMAL の状態で開始します。以前のビットマスクで指定されていなかったものは、明示的にオフにしてください。

各 Navigator.AudioGuidance フラグを、次の AudioGuidanceSettings.Builder の呼び出しに対応させます。

  • SILENT:setGuidanceMode(GuidanceMode.SILENT)
  • VOICE_ALERTS_ONLY:setGuidanceMode(GuidanceMode.VOICE_ALERTS_ONLY)
  • VOICE_ALERTS_AND_GUIDANCE: setGuidanceMode(GuidanceMode.VOICE_ALERTS_AND_GUIDANCE)
  • VIBRATION が設定されている/いない場合:setVibrationEnabled(true) / setVibrationEnabled(false)
  • BLUETOOTH_AUDIO が設定されている/いない場合:setBluetoothAudioEnabled(true) / setBluetoothAudioEnabled(false)
// Before: navigator.setAudioGuidance(
//     Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE | Navigator.AudioGuidance.BLUETOOTH_AUDIO);
navigator.setAudioGuidanceSettings(
    AudioGuidanceSettings.builder()
        .setGuidanceMode(AudioGuidanceSettings.GuidanceMode.VOICE_ALERTS_AND_GUIDANCE)
        .setBluetoothAudioEnabled(true)
        .setVibrationEnabled(false) // VIBRATION was not in the old bitmask
        .build());
フェーズ 5:検証して報告する
  1. debug と release の両方のバリアントをビルドします。R8 のみで発生する問題(Android Auto の keep ルール、AGP 9 で禁止されているコンシューマー keep ルール)は、release でのみ発生します。
  2. 非推奨の警告を確認します。Kotlin ではデフォルトで w: 行が出力されます。Java の場合は、tasks.withType(JavaCompile) に options.compilerArgs += ["-Xlint:deprecation"] を追加するか、ファイルごとの「uses or overrides a deprecated API」という注記を確認してください。フェーズ 0 の grep を再実行します。削除されたシンボルが残っていないことを確認してください。残っている非推奨の使用箇所は、ユーザーが移行を延期することにしたものに限られている必要があります。
  3. ユーザーに簡潔なレポートを提示します。
    • 変更内容(ツールチェーン、依存関係、呼び出し箇所)。
    • 移行を延期した非推奨項目と、そのファイルの場所および削除予定のバージョン(9.0、約 1 年後、または今後のリリース)。
    • コード以外の対応事項:Play Console の Location Purpose Declaration と、オプションで、新しいオフルート交通事故カードについて説明します。このカードは交通レイヤーが有効な場合、デフォルトでオンです。アプリの UX 上必要であれば、NavigationView / NavigationFragment で setTrafficIncidentCardsEnabled(false) を呼び出して無効にできます。

検証チェックリスト

  • AGP >= 9.0.1 で、AGP が要求するバージョンの Gradle を使用していること。Gradle JDK >= 17、compileSdk / targetSdk は 37、NavSDK の依存関係は 8.0.x であること。
  • インポートが引き続き com.google.android.libraries.navigation.* であること。 NavigationApi.getNavigator(...) の初期化に変更がないこと。RouteStatus は引き続き enum として使用されていること。
  • showTrafficLights、showStopSigns、onGpsAvailabilityUpdate への参照がないこと。
  • RouteStatus の網羅的な処理で ROUTING_TIMEOUT に対応していること。 RouteStatus.NETWORK_ERROR の処理が維持されていること。
  • getNavigator の onError で ErrorCode.NETWORK_ERROR を再試行するように処理していること(getNavigator(Application, ...) から発生する場合があります)。
  • アプリで直接使用する場合に限り、kotlin-reflect / Glide を宣言していること。Android Auto を使用する場合、androidx.car.app >= 1.3.0 であること。
  • StylingOptions を parcel 化していないこと。ナビゲーション中に地形が表示されないこと。
  • 非推奨項目を移行済み(レイアウト XML の SupportNavigationFragment を含む)であるか、延期項目としてレポートに記載していること。
  • debug と release のビルドが成功すること。Play Location Purpose Declaration についてユーザーに注意喚起していること。

コメント