ガイド変更履歴HERE SDK API references
ガイド

デバッグとトラブルシューティング

このセクションでは、効果的なデバッグとトラブルシューティングのテクニック、一般的な問題、洞察に富んだログの生成方法について説明します。

一般的な問題

問題が発生した場合は、まず最小要件サポートされるデバイスChangeLogに掲載されている既知の問題のリストを確認してください。

  • **空白の白いマップのみが表示されます。**ご利用のHERE Credentialsが有効で、「利用開始」トピックの説明に従って設定されていることを確認してください。また、ご利用のデバイスがインターネットに接続できることを確認してください。インターネット接続が遅い場合、最初に読み込まれたマップ タイルが表示されるまでにしばらくかかることがあります。また、デバイスの時刻が正しく設定されていることを確認してください。まれに、デバイスの時間が正しく設定されていないと、一部のバックエンド サービスで認証の問題が発生する可能性があります。
  • **ログに "No map content will be displayed until valid config is provided." と表示される:**コードで実際に loadScene() を呼び出していることを確認してください。
  • **アプリがクラッシュし、ログに "CL_magma - Couldn't load the default shader." と表示される:**お使いのデバイスが OpenGL ES 3.0 に対応している必要があります。シミュレーターを実行している場合は、[設定]、[Advanced](詳細)、[OpenGL ES API level](OpenGL ES API レベル) の順に選択してエミュレータの設定を編集します。[Autoselect](自動選択) に設定されている場合は [Renderer Maximum](最高レンダラー) に変更してみてください。この問題は主に Windows マシンで発生します。
  • **':app@debug/compileClasspath' の依存関係を解決できません:HEREsdk-YOUR_SDK_VERSION が見つかりません。**アプリケーションの構築 gradle ファイルの名前と HERE SDK AAR が一致していることを確認してください。注:バージョンを明示的に参照する場合にのみ必要です。どのバージョンにも一致するワイルドカードとして *.aar を使用するため、上記の手順に従うとこれを実行する必要はありません。
  • **"License for package Android SDK Platform not accepted." というエラーやそれに類似するエラーが表示されます。**必要なツールをインストールし、ライセンス ボタンをクリックしたり、ターミナルから cd /d "%ANDROID_SDK_ROOT%/tools/bin"sdkmanager --licenses を呼び出したりするなどの操作を行って、すべての Android ライセンスに同意していることを確認してください。
  • **クラッシュログに"Exception was thrown in Java and it was not handled." と記録されています。**HERE SDK では、コールバック内のアプリ側でスローされたランタイム例外を処理できません。このような場合にこのエラー ログが表示されます。つまり、アプリケーションが処理する HERE SDK コールバックの 1 つで、コードが例外をスローします。
  • キャッシュのロックによりクラッシュが発生しています。Storage.LevelDB エラーまたは FAILED_TO_LOCK_CACHE_FOLDER エラーが原因でアプリケーションがクラッシュした場合は、こちらの指示に従ってこのようなクラッシュが再度発生しないようにします。
  • マップが表示されないか、HERE SDK が何も呼び出しません。"These credentials do not authorize access" というログ メッセージが表示された場合は、資格情報が有効ではありません。有効な資格情報を使用していることを確認してください。3.xバージョンの資格情報には互換性がありません。Exploreの資格情報はNavigateと互換性がありません。
  • **マップビューに表示上の不具合があります。**一部の Android バージョンでこの問題が発生する可能性があり、MapRenderMode.texture を使用して修正できます。詳細については、マップ ガイドを参照してください。
  • **Android エミュレータでアプリをもう一度開くと、空白のマップが表示されます:**これは Android エミュレータ 34.2.14 および 34.2.13 の既知の問題です。Googleが問題を修正するまで、安定版チャネルからAndroidエミュレータ34.1.20またはそれ以前を使用してください。この問題は、APIレベル28の画像を使用するAndroidエミュレータでも発生することがあります。
  • Android Studioはアプリをコンパイルせず、「プロジェクトのGradleバージョンは、GradleのJavaバージョンとの互換性がありません」というビルドエラーが表示されます。このようなエラーは、新しいAndroid Studioバージョンへの切り替えの際に発生する可能性があります。「利用開始」ガイドに従い新しいアプリを一からビルドするか、gradle-wrapper-propertiesdistributionURLを新しいバージョンに設定してGradleを更新し、さらにプロジェクトのbuild.gradleファイル内のdependenciesクロージャーでclasspathを使用してAGPを更新します。AGPプラグインとGradleのバージョンが一致していることを確認します。
  • **大規模な更新やストレージの急増を避けてオフラインマップを管理するには、**ナビゲートライセンスを使用する場合、MapDownloaderでインストール済みのRegionsをクエリし、ダウンロード済みリージョンを監視し、更新サイズを見積もり、不必要なダウンロードを避けます。更新をトリガーする前に、既存のリージョンサイズを比較します。より細かく制御する場合は、自動更新を無効にします。詳細については、こちらを参照してください。

ロック処理を解除するには

まれに、Storage.LevelDB エラーが原因で HERE SDK を使用するアプリケーションがクラッシュしたり、HERE SDK の初期化に失敗して FAILED_TO_LOCK_CACHE_FOLDER エラーが発生したりすることがあります。

これは、SDKNativeEngine の 2 番目のインスタンスが既存のインスタンスと同じ access_key_id で作成された場合に発生する可能性があります。その結果、ローカルの地図キャッシュ ディレクトリが現在の処理によってロックされます。

このキャッシュ フォルダーがロックされるクラッシュは、HERE SDK を初期化する前に、次のオプションを設定することで修正できます。

// Set your credentials for the HERE SDK.
AuthenticationMode authenticationMode = AuthenticationMode.withKeySecret("YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET");
SDKOptions sdkOptions = new SDKOptions(authenticationMode);

// Defaults to SDKOptions.ActionOnCacheLock.WAIT_LOCKING_APP_FINISH.
sdkOptions.actionOnCacheLock = SDKOptions.ActionOnCacheLock.KILL_LOCKING_APP;

// Now, use these options to initialize the HERE SDK and destroy a locking process (if any).
try {
    SDKNativeEngine.makeSharedInstance(context, sdkOptions);
} catch (InstantiationErrorException e) {
    throw new RuntimeException("Initialization of HERE SDK failed: " + e.error.name());
}

キャッシュ ロックが発生した場合、ロック処理は強制終了され、アプリは正常に起動できます。キャッシュ ロックが発生しなかった場合、このコードは HERE SDK の初期化のみを行います。KILL_LOCKING_APP の他に、次の値も設定できます。

  • NO_ACTION:何も行われません。
  • WAIT_LOCKING_APP_FINISH:アプリはロック処理が終了するまで待機します。これは決して起こらない可能性があることに注意してください。これはデフォルトの動作です。

別の方法として、次のスニペットを使用して、キャッシュロックの問題を検出し、防止することができます。このフラグが設定されている場合、makeSharedInstance() は内部で destroyLockingProcess() を呼び出すため、KILL_LOCKING_APP と同じ効果がありますが、より柔軟性があります。

// Check if there is a lock on the cache.
Integer processID = LockingProcess.getLockingProcessId(sdkOptions);
if (processID != null) {
    // Warning: The cache is locked.

    // This may kill another process that is trying to attempt to lock the current map cache.
    // If this happens, the method will try to gracefully repair the cache.
    // If no problem was detected, the method will do nothing.
    long maxTimeoutInMilliseconds = 300;
    LockingProcess.destroyLockingProcess(sdkOptions, maxTimeoutInMilliseconds);
}

// Now, proceed to initialize the HERE SDK.

getLockingProcessId() は、Android OS からロック処理のプロセス ID を提供します。ロックが発生しなかった場合、このメソッドは null を返します。

destroyLockingProcess() を呼び出すことにより、問題は解決します。このコードを保持しておくと、アプリケーション起動時の散発的なクラッシュを解決できます。キャッシュ ロックが検出されない場合、destroyLockingProcess() は何も行いません。

ログ レベルで指定する

LogControl クラスでは、アプリのリリース ビルドであっても、事前定義されたさまざまな LogLevel 値の HERE SDK メッセージをログに記録できます。LogControl は必ず HERE SDK を初期化する前に呼び出してください。

// Disable any logs from HERE SDK.
// Make sure to call this before initializing the HERE SDK.
LogControl.disableLoggingToConsole();

上のコマンドにより、HERE SDK 関連のすべてのコンソール ログを無効化できます。なお、問題を調査する際に重要となるログメッセージが失われる可能性があるため、デバッグ ビルドではこれはお勧めしません。

ログ レベルは次のように指定できます。

LogControl.enableLoggingToConsole(LogLevel.LOG_LEVEL_INFO);

LogLevel を指定する場合、以下の階層に基づいて、報告されるメッセージの最小レベルを設定します。

  1. LOG_LEVEL_INFO
  2. LOG_LEVEL_WARNING
  3. LOG_LEVEL_ERROR
  4. LOG_LEVEL_FATAL

たとえば、LOG_LEVEL_ERROR を設定する場合、LOG_LEVEL_INFO および LOG_LEVEL_WARNING はログから除外されます。その他はすべてログに記録されます。

LOG_LEVEL_OFFを設定すると、すべてのログが記録されなくなります。

すべてのログメッセージには、先頭に「hsdk-」が付いており、HERE SDKからのメッセージを簡単に識別できます。

また、LogAppenderインターフェースを使用すると、独自のログクラスをLogControlクラスに挿入できます。これにより、さまざまなランタイム条件に基づいてログメッセージをフィルタリングできます。たとえば、LOG_LEVEL_ERRORタイプのエラーのみをログに記録するように選択できます。デフォルトでは、このようにログを選択的に記録することはできません。これは、どのメッセージの記録を許可するかを判断するのはログ階層のみであり、HERE SDKの初期化後にこの最小レベルを調整することはできないためです。ただし、独自のロギングクラスを追加すると、完全に制御できるようになります。

有意義なログを生成する

多くの問題では、IDE (統合開発環境) のコンソールに表示されるログに、最も関連性の高い情報がすでに含まれています。クラッシュや ANR については、さらに内容を掘り下げ、デバイス ログを確認することをお勧めします。logcat を使用する場合は、タイムスタンプを使用して最新のログのみを記録します。

例:

adb logcat -t '06-30 16:30:00.820' > /Users/name/Desktop/log.txt

できれば、adb logcat -c を使用して問題の再現を開始する前にすべてのログを消去します。

Google Play Console でクラッシュ ログをシンボル化する

Google Play ストアにデプロイされたアプリの場合、次のようにアプリの各バージョンにシンボル ファイルをアップロードして、クラッシュ レポートを取得する必要があります。

  1. Google Play Console を開き、アプリを開きます。
  2. 左側のメニューで、[Release](リリース) > [App bundle explorer](アプリ バンドル エクスプローラ) を選択します。
  3. 右上のピッカーを使用して、デバッグ シンボルのある ZIP アーカイブを選択します。
  4. [ダウンロード] タブを選択し、[アセット] セクションまで下にスクロールします。
  5. 該当するデバッグ シンボルのアップロード矢印をクリックして、アプリのバージョンのシンボル ファイルをアップロードします。詳細については、こちらを参照してください。
  6. その後、クラッシュと ANR が難読化解除されます。アプリの個々のクラッシュと ANR の難読化解除されたスタック トレースを表示するには、Google Play Console のクラッシュと ANR ページに移動します。

クラッシュ ログのシンボル化はローカルでも実行可能

ネイティブ クラッシュをローカルでシンボル化するには、次の手順を実行します。

  1. Logcat または ADB を使用してクラッシュ ログを収集し、.txt ファイルに保存します。
adb logcat -d > your_crashlog_filename.txt
  1. リリース パッケージに付属しているシンボルの .so ファイルを取得します。これらの .so ファイルは、debug-symbols ZIP ファイル内にあります。
  2. ビルド アーキテクチャに応じて、arm64-v8a または armeabi-v7a のファイル パスをコピーします。
  3. ndk-stack ツール コマンドを実行します。
path-to-Andorid-sdk/Android/sdk/ndk/24.0.8215888/ndk-stack -sym path-to-directory-with-binary-of-desired-architecture -dump path-to-crash.txt

なお、本リリースでは「NDK 24.0.8215888」を使用してください。


EN 日本語

HERE documentation

Find answers to your product and technical questions

Documentation

What's new

Videos

EN 日本語

HERE ドキュメント

製品や技術に関する質問の答えを見つけましょう。より多くの内容と最新の情報については、英語版をご覧ください。

ドキュメント

ダイナミックマップ

動的コンテンツ関連のAPIをアプリやサービスに活用して、ドライバーが安全・快適かつ予定どおりに目的地へ到着できるよう支援します。

地図とデータ

世界中を走行する多数のマッピング車両から得られる最新の位置情報データを活用し、精度の高い地図やカスタムレイヤーを構築できます。

最新情報

動画

(function () { const input = document.querySelector('input[data-typeahead]'); if (!input) return; // Prevent the form from submitting/navigating input.closest('form')?.addEventListener('submit', e => e.preventDefault()); input.addEventListener('input', function () { const q = this.value.trim().toLowerCase(); document.querySelectorAll('.nav-group-name').forEach(group => { let anyVisible = false; group.querySelectorAll('.nav-group-task').forEach(task => { const text = task.textContent.trim().toLowerCase(); const show = !q || text.includes(q); task.style.display = show ? '' : 'none'; if (show) anyVisible = true; }); // Hide the whole group header if nothing matches group.style.display = anyVisible || !q ? '' : 'none'; }); }); })(); (function () { function onTokenClick(event) { var link = event.target.closest('.sdk-for-ios .item .token'); if (!link) return; event.preventDefault(); console.log('token clicked', link.textContent.trim()); var item = link.closest('.item'); if (!item) return; var content = item.querySelector('.height-container'); if (!content) { console.log('no .height-container found for item', item); return; } var isHidden = window.getComputedStyle(content).display === 'none'; content.style.display = isHidden ? 'block' : 'none'; link.classList.toggle('token-open', isHidden); var href = link.getAttribute('href'); if (href) { if (history.pushState) history.pushState({}, '', href); else location.hash = href; } } function openHashTarget() { var hash = window.location.hash.slice(1); if (!hash) return; var anchor = document.querySelector('.sdk-for-ios a[name="' + hash + '"]'); if (!anchor) return; var item = anchor.closest('.item'); if (!item) return; var link = item.querySelector('.token'); var content = item.querySelector('.height-container'); if (!link || !content) return; content.style.display = 'block'; link.classList.add('token-open'); } function init() { console.log('HERE SDK accordion init'); openHashTarget(); } document.removeEventListener('click', onTokenClick); document.addEventListener('click', onTokenClick); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } window.addEventListener('hashchange', openHashTarget); window.addEventListener('pageLoad', init); })();