現在地を検索
マッピングアプリケーションを使用する主な理由の 1 つは、自分がどこにいるかを確認することです。
HERE SDK が提供するLocationEngine
は、 GPS やその他のグローバル衛星ナビゲーションシステム( GNSS )受信機、モバイルネットワーク信号、 Wi-Fi ネットワーク信号などの複数の位置情報源と連携して正確な位置を判断する、包括的な位置情報ソリューションを実装しています。
iOS デバイス 自体が GNSS 精度に対応している場合は、 iOS デバイス のハードウェアに依存します。 サブメーターの精度は現在 iOS ではサポートされていないため、別のレシーバーが必要です。 Android デバイスでは、サブメーターの精度は、資格情報 が有効になっている場合にのみサポートされます ( 以下を参照 ) 。
注
簡単に確認できます
HERE SDK の位置情報フィーチャーを統合するには、少なくとも次の手順を実行する必要があります。
- マニフェストファイル( Android の場合)およびファイル
.plist
( iOS の場合)に必要な権限を追加し、ユーザーに権限を要求します。 - データを
LocationEngine
によって収集できるかどうかを確認する承諾ダイアログConsentEngine
を作成して表示します。 - 承諾ダイアログの結果を表示し、ユーザーが以前の決定を削除できるようにします。
LocationEngine
を作成し、少なくとも 1 つのLocationListener
を設定します。 -
LocationEngine
を1回開始し、必要な精度レベルを設定します。 Location
の更新を受信し、アプリで処理します。
必要な権限を追加
フラッター自体には、権限の処理はありません。 そのため、 Android および iOS のネイティブプロジェクト用に、生成されたファイルをいくつか調整する必要があります。
まず、 Android を使用してみましょう。
Android デバイスのアプリでのLocationEngine
の使用を開始する前に、アプリ のAndroidManifest.xml
ファイルに必要な権限を追加する必要があります( _PROJECT_dir/Android/app/src/main/ にあります)。
...
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
注
アプリが Android SDK バージョン 31 以降を対象とする場合 、アプリのユーザーはデバイスの「正確な」位置情報を付与する必要があります。 プロンプトが表示された場合 、「近似」の精度を選択するだけでは不十分です。 したがって 、上記のように、マニフェストファイルにACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
権限が存在する必要があります。 HERE Positioning で GNSS を使用し、携帯電話および WiFi スキャンを行うには、ファインロケーション許可が必要です。 このACCESS_COARSE_LOCATION
権限だけでは、 HERE Positioning が動作するのに十分ではない近似の精度になるため、十分ではありません。 この場合、LocationEngine
は MISSING_PERMISSIONS
エラーで失敗します。
WAKE_LOCK
HERE SDK によって権限が強制されませんが、アプリケーションに権限が付与されている場合、 HERE SDK はウェークロックを使用して、省電力モードになっているデバイスによってネットワークスキャンおよび位置の計算が中断されないようにします。 ウェイクロックは、バッテリー消費への影響をできるだけ少なくするために、必要な時間だけ保持されます。 Android オペレーティング システムは、ウェイクロックを継続的に維持しているアプリケーションまたはサービスがバッテリー消費の原因であることに注意してください。そのため、アプリケーションをユーザーにとって魅力的な状態に保つには、ウェイクロックがユースケースにとって必須であるかどうか、またはウェイクロックが必須であるかどうかを慎重に検討する必要があります。
次に、 iOS に移動します。
アプリ Info.plist
のファイルに追加 します( _PROJECT_dir/ios/Runner/に あります)。
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>location-services</string>
<string>gps</string>
</array>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs to access your current location to display it on the map.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs to access your current location to display it on the map.</string>
<key>NSMotionUsageDescription</key>
<string>Motion detection is needed to determine more accurate locations, when no GPS signal is found or used.</string>
注
バックグラウンド NSLocationAlwaysAndWhenInUseUsageDescription
で位置情報の更新を要求する場合にのみ、権限が必要になります。
permission_handler プラグインを使用して、ユーザーから特定の権限を要求できます。 詳細については、プラグインの公式サイトを参照してください。 または、 HERE SDK for iOS for the HERE SDK for Android and 開発者ガイド for the 開発者ガイドの「 Find Your Location 」セクションで、権限を要求するためのプラットフォーム固有のコードを見つけることもできます。
GPS などのネイティブの位置情報サービスを使用するアプリは、ユーザーの許可を要求します。 すべてのデバイスが同じ機能を提供しているわけではありません。また、特定のハードウェアの制約があるため、結果が異なる可能性があります。
注
最近の iPad または Android タブレットデバイスであっても、 UIRequiredDeviceCapabilities
に必要なものが不足 gps
している可能性があります。 Info.plist
ファイルに存在する場合、アプリ はこのようなデバイスにインストールされません。 この機能を削除すると、アプリ がインストールされますが Location
、デバイスから受け取る更新の精度は半径が大きくなり、結果として非常に不正確になります。 GPS センサーがない場合、デバイスはネットワークの配置などにフォールバックすることがあります。
を使用する前 LocationEngine
に、ネイティブの位置情報サービスが有効になっているかどうかを確認することをお勧めします。 ほとんどの Android デバイスでは、ユーザーが位置情報サービスをオンにすることを選択できます。さらに、デバイスの [ 設定 ] を開き、 [ セキュリティと位置情報 ] セクションに移動することで、精度を上げることもできます。 ほとんどの iOS デバイスでは、ユーザーは [ 設定 ] > [ プライバシー ] > [ 位置情報サービス ] の順に移動して位置情報サービスがオンになっていることを確認できます。
に LocationEngine
は、 HERE SDK が使用する HERE サービスを改善するために、モバイル機器の周辺についての特定の情報を収集できる機能が含まれています。 そのような情報の例として、近くの Wi-Fi およびモバイルネットワークの信号の強度があります。
HERE SDK は ConsentEngine
、ユーザーがデータを収集することに同意したことを取得するためのフローを処理するを提供します。 さらに、現在のステータスを取得し、データを収集するかどうかを判断する前の決定を削除できます。 アプリケーションは、ユーザーがいつでもアクセスできるようにする必要があります。
注 : 要件
承諾ダイアログの表示は必須です。 LocationEngine
は、ユーザーが決定するまで位置情報データをアプリ に送信しません。 ユーザーが承諾を付与または拒否した場合でも、LocationEngine
完全に動作可能になります。
次の 2 つのステップが必要です。
-
consentEngine.requestUserConsent()
を呼び出して、承諾ダイアログを表示します。 - アプリケーションは、ユーザーの現在の決定内容を表示し、以前の決定内容を削除する必要があります。
consentEngine.userConsentState
経由で現在の決定を取得します。 ユーザーが再度 consentEngine.requestUserConsent()
をコールすることを許可して、前の決定を取り消します。 これは、アプリのライフサイクル中いつでも可能である必要があります。
これらの手順については、以下で詳しく説明します。 詳細については、 HERE SDK のプライバシーに関する補足情報を参照してください。 情報は、ユーザーが同意した場合にのみ収集されることに注意してください。 収集された情報はユーザーを特定するものではなく、 HERE は匿名化された情報のみを保持します。
注 : 上記の要件は、現在 iOS プラットフォームにデータ収集がないため、 Android アプリケーションにのみ適用されます。 これは今後変更される可能性があります。
iOS デバイスでは、呼び出し consentEngine.requestUserConsent()
によってダイアログが表示されますが 、呼び出す必要はありません。 デフォルトの承諾状態はです notHandled
。 iOS では、 ConsentEngine
のメソッドおよびプロパティ(userConsentState
、 grantUserConsent()
および denyUserConsent()
)は Android と同じように動作しますが 、 iOS では処理しないことをお勧めします。 Android で は、有効な状態(granted
または denied
)を設定するための承諾を要求する必要があるため、notHandled
状態によってLocationEngine
を使用できません。 iOS で LocationEngine
は、状態に関係なく、はすぐに使用できます。
ローカリゼーションの設定中です
承諾エンジンは、最大 31 の言語をサポートしています。 ダイアログが表示されたときに使用された言語は、現在のデバイスの言語設定に基づいて自動的に選択されます。 デバイスの言語がサポートされている言語でない場合は、代わりに英語が使用されます。 以下のコード スニペットでは、ローカライズされた承諾ダイアログをサポートするようにアプリケーションを設定する方法を示します。
import 'package:flutter/material.dart';
import 'package:here_sdk/consent.dart';
import 'PositioningExample.dart';
void main() {
runApp(
MaterialApp(
localizationsDelegates: HereSdkConsentLocalizations.localizationsDelegates,
supportedLocales: HereSdkConsentLocalizations.supportedLocales,
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
@override
PositioningExample createState() => PositioningExample();
}
ユーザーの同意を要求しています
LocationEngine
を開始する前 に、前述の情報を収集するユーザーの同意が得られていることを確認する必要があります。 回答の内容に関係なく ( ユーザーがデータの収集を承諾したかどうかに関係なく ) 、承諾ダイアログが表示され、回答が提供されたことのみが該当します。 LocationEngine
は、ユーザーの同意を得ずに開始しようとすると、LocationEngineStatus.USER_CONSENT_NOT_HANDLED
ステータスを返します。
以下のコード スニペットは、 ConsentEngine
のインスタンスを作成し、ユーザーの同意がすでに要求されているかどうかを確認します。要求されていない場合は、ユーザーに収集された情報の詳細を説明する UI ダイアログ ( 以下の図も参照 ) を呼び出します。 権限を付与または拒否することができます。
try {
_consentEngine = ConsentEngine();
} on InstantiationException {
throw ("Initialization of ConsentEngine failed.");
}
Future<void> _ensureUserConsentRequested() async {
if (_consentEngine.userConsentState == ConsentUserReply.notHandled) {
await _consentEngine.requestUserConsent(context);
}
_updateConsentInfo();
_startLocating();
}
マップ シーンのロード中は、requestUserConsent()
を呼び出さないことをお勧めします。
のコード _updateConsentInfo()
は HERE の外にあります。 基本的に、ユーザーの現在の承諾の決定が表示されます。
スクリーンショット: 承諾のダイアログ。 このダイアログには、 HERE のプライバシープラクティスについて説明した Web ページへのリンクが含まれており、 37 言語をサポートしています。 表示されているダイアログは、デバイスの言語設定に従って表示されます。サポートされていない場合は、英語で表示されます。
ユーザーの応答は、アプリケーションの使用セッション間で保持され、 userConsentState
プロパティを使用して取得できます。このプロパティは Consent.UserReply
、次の値を返します。
switch (_consentEngine.userConsentState) {
case ConsentUserReply.granted:
break;
case ConsentUserReply.denied:
break;
case ConsentUserReply.notHandled:
break;
case ConsentUserReply.requesting:
break;
default:
throw Exception("Unknown consent state.");
}
アプリケーションは、プロパティにアクセスして、ユーザーが以前に入力した応答を参照できるようにする必要 userConsentState
があります。 また、 requestUserConsent()
このアプリケーションでは、メソッドを呼び出して承諾ダイアログを再度表示することで、いつでもユーザーが同意についての考え方を変更できるようにする必要があります。
Android で requestUserConsent()
は、が呼び出されると、 HERE SDK に Activity
ダイアログを含む新しいが表示されます。 ダイアログが閉じると、前の Activity
ダイアログが再開されます。 MapView
ダイアログを開く前にが表示 MapView
されている場合、は再び表示されるまで一時停止されます。
注 : 重要
現在、 iOS プラットフォームにはデータ収集がありません。 これは今後変更される可能性があります。 それまでの間、上記の要件は Android アプリケーションにのみ適用されます。 以下のコード スニペットでは、 Android プラットフォームでユーザーが承諾に与えた応答、およびユーザーの心理を変更できることを示す画面を実装する方法を 1 つ示しています。 また、他のプラットフォームでは、データ収集がないことをユーザーに通知するメッセージが表示されます。
import 'dart:io' show Platform;
class ConsentPreferencesPage extends StatefulWidget {
ConsentPreferencesPage({Key key, this.title}) : super(key: key);
final String title;
@override
State<ConsentPreferencesPage> createState() {
if (Platform.isAndroid) {
return _ConsentPreferencesPageAndroid();
}
return _ConsentPreferencesPageOther();
}
class _ConsentPreferencesPageAndroid extends State<ConsentPreferencesPage> with WidgetsBindingObserver {
try {
_consentEngine = ConsentEngine();
} on InstantiationException {
throw ("Initialization of ConsentEngine failed.");
}
String _getConsentAnswer() {
switch (_consentEngine.userConsentState) {
case ConsentUserReply.granted:
return "You have granted consent to the data collection.";
case ConsentUserReply.denied:
case ConsentUserReply.notHandled:
case ConsentUserReply.requesting:
return "You have denied consent to the data collection.";
default:
throw Exception("Unknown consent state.");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
margin: const EdgeInsets.only(left: 25, right: 25),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Text(
'The Location Engine contains functionality that can gather certain '
'information about the surroundings of the mobile device in order '
'to improve the HERE services used by the HERE SDK. An example '
'of such information is the strength of the nearby Wi-Fi and '
'mobile network signals.'
),
),
SizedBox(height: 20),
Flexible(
child: Text(
_getConsentAnswer(),
),
),
SizedBox(height: 20),
PlatformButton(
child: const Text("Manage Consent"),
onPressed: () {
setState(() {
_consentEngine.requestUserConsent(context);
});
}
),
],
),
),
);
}
class _ConsentPreferencesPageOther extends State<ConsentPreferencesPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
margin: const EdgeInsets.only(left: 25, right: 25),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Text('This app does not collect any data on this platform.'),
),
]
)
)
);
}
}
注
サンプルのフローは 、 GitHub にある Positioning Example アプリに記載されています。
承諾ダイアログのカスタマイズ
LocationEngine
を使用するには、ユーザーの同意を要求する必要があります。 既定では、上記の API を使用してこの問題が発生します。
ダイアログの外観と内容をカスタマイズできます。 このためには、 HERE に、アプリケーション独自にカスタマイズしたユーザーの同意ダイアログを証明するよう依頼します。 証明書を受け取ると、アプリケーションは grantUserConsent()
と denyUserConsent()
のメソッドを使用して HERE SDK に対するユーザーの応答を伝達できます。HERE が、アプリケーションによってカスタムダイアログを開始できることを承認した場合、requestUserConsent()
の呼び出しは不要になります。 通信したユーザーの応答は HERE SDK によって保持 getUserConsentState()
され、メソッドを使用して以前に指定した応答を取得できます。
特定の事前要件の下で、別の方法で承諾の決定を要求または更新することも可能です。 たとえば、ユーザーがすでに外部の Web サイトで承諾を付与している場合です。 ただし、ソリューションについては、 HERE チームと個別に話し合う必要があります。
このオプションの詳細について確認 するか、または HERE の営業担当者またはヘルプページから HERE に連絡して認定プロセスを開始してください。
LocationEngine を作成します
LocationEngine
の新規作成は簡単です。
try {
_locationEngine = LocationEngine();
} on InstantiationException {
throw ("Initialization of LocationEngine failed.");
}
注
Application
のonCreate()
ライフサイクル中は、LocationEngine
を初期化できません。 それ以外の任意の時点で問題はありません。 たとえば、エンジンを初期化するのに適した場所が Activity
の onCreate()
メソッドに含まれている可能性があります。
最後に確認した場所を取得
エンジンが初期化されると、少なくとも 1 回前にエンジンが始動し、少なくとも 1 つの位置を受信している限り、最後に確認された位置を取得できます。そうでない場合、null
が返されます。 この情報は残ります。したがって、最後に確認された場所もアプリケーションセッション間で利用できます。
Location? myLastLocation = _locationEngine.lastKnownLocation;
if (myLastLocation != null) {
print("Last known location: " + myLastLocation.coordinates.latitude.toString() + ", " + myLastLocation.coordinates.longitude.toString());
}
注
LocationEngine
最後の既知の場所を取得するために、を開始する必要はありません。また、リスナーを設定する必要もありません。 が LocationEngine
前のセッションで 1 回正常に開始され、有効な位置イベントが少なくとも 1 回受信されただけで十分です。 Location
オブジェクトには timestamp
、その場所がいつ受信されたかを示すが含まれています。
位置情報イベントに関する通知を受信
次に、 LocationEngine
を開始する前に LocationStatusListener
を登録して、エンジンのステータスの変更が通知されるようにすることをお勧めします。 そのためには LocationStatusListener
、抽象クラスを実装し、 Location Engine addLocationStatusListener()
のメソッドに登録します。 さまざまなステータスの詳細については、 API リファレンス を確認してください。
class PositioningExample extends State<MyApp> implements LocationStatusListener {
@override
onFeaturesNotAvailable(List<LocationFeature> features) {
for (var feature in features) {
print("Feature not available: " + feature.toString());
}
}
@override
onStatusChanged(LocationEngineStatus locationEngineStatus) {
print("LocationEngineStatus: " + locationEngineStatus.toString());
}
_locationEngine.addLocationStatusListener(this);
注
開始が成功すると、LocationStatusListener
は常にステータスLocationEngineStatus.engineStarted
を受信し、停止が成功すると、常にステータスLocationEngineStatus.engineStopped
を受信します。
また、リスナー onFeaturesNotAvailable()
のコールバック を通じて LocationFeature
、利用できないものがあれば通知されます。 必要な機能が利用できない場合は、HERE の担当者にご連絡ください。
エンジンを始動する前に考慮すべき最後の作業は、LocationListener
を登録することです。これにより、新しいLocation
が検出されたときに通知を送信するonLocationUpdated()
コールバックが提供されます。 これは、前述のLocationStatusListener
と同様の方法で行うことができます。
class PositioningExample extends State<MyApp> implements LocationListener {
@override
onLocationUpdated(Location location) {
print("Received location: " + location.coordinates.latitude.toString() + ", " + location.coordinates.longitude.toString());
}
_locationEngine.addLocationListener(this);
注
コールバック onLocationUpdated()
はメインスレッドで受信されます。他のすべてのコールバックと同じです。
現在の地理座標およびタイムスタンプを除き、その他 Location
のすべてのフィールドはオプションです。 たとえば、受信 したオブジェクトLocation
には、ベアリング角度および現在の速度に関する情報が含まれている場合がありますが、この情報は利用できることは保証されていません。 使用できない値は、として返さ null
れます。 ポジショニングに使用されるソースの種類( エンジンの始動に使用されるLocationAccuracy
によって定義されます。以下の「 Start and Stop Receiving Locations 」セクションを参照してください)と、デバイスの機能が利用可能なフィールドに影響を与えます。
それぞれのaddLocationStatusListener()
メソッドおよびaddLocationListener()
メソッドを呼び出して、必要なだけLocationStatusListener
およびLocationListener
を追加できます。
受信地点の開始および停止
LocationEngine
の startWithLocationAccuracy()
メソッドを呼び出す準備ができました。
class PositioningExample extends State<MyApp> implements LocationListener, LocationStatusListener {
try {
_locationEngine = LocationEngine();
} on InstantiationException {
throw ("Initialization of LocationEngine failed.");
}
try {
_consentEngine = ConsentEngine();
} on InstantiationException {
throw ("Initialization of ConsentEngine failed.");
}
if (_consentEngine.userConsentState == ConsentUserReply.notHandled) {
await _consentEngine.requestUserConsent(context);
}
_updateConsentInfo();
_startLocating();
void startLocating() {
_locationEngine.addLocationListener(this);
_locationEngine.addLocationStatusListener(this);
_locationEngine.startWithLocationAccuracy(LocationAccuracy.bestAvailable);
}
エンジンを始動する最も簡単な方法は、上記のコード スニペットのように、定義済みのモードの 1 つLocationAccuracy
を渡すことです。 使用可能なすべてのモードの詳細については、次の表を参照するか、 API リファレンス を確認してください。
LocationEngine
が開始された後、最初にstop()
をコールしないで、再度開始しようとすると、LocationEngineStatus.alreadyStarted
が届きます。 このメソッドisStarted()
を使用して、エンジンが始動しているかどうかを確認できます。 同様に、LocationEngine
を開始し、最初のを停止せずに別のを開始しようとすると、LocationEngineStatus.alreadyStarted
エラーが発生します。 一度に始動できるエンジンは 1 つだけです。
位置情報の更新をこれ以上受信したくない場合 stop()
は、メソッドを呼び出してエンジンを停止できます。 不要になったリスナーは必ず削除してください。
void stopLocating() {
_locationEngine.removeLocationStatusListener(this);
_locationEngine.removeLocationListener(this);
_locationEngine.stop();
}
一般 的に、アプリの廃棄時に、AppLifecycleState
を聴いてLocationEngine
を停止することをお勧めします。 GitHub の例については、positioning_app
を参照してください。
iOS デバイスで停止中に更新を一時停止します
iOS デバイスで LocationEngine
は、はデフォルトで、位置情報の変更が予期されない場合に位置情報の更新を一時停止します。 これを使用すると、たとえば、デバイスが静止しているときのバッテリー寿命を改善できます。 この機能は、メソッドで制御 LocationEngine.setPauseLocationUpdatesAutomatically()
できます。
注
Android の plaftorms で setPauseLocationUpdatesAutomatically()
は、が返さ LocationEngineStatus.notSupported
れます。
バックグラウンド更新を有効化
アプリケーションがバックグラウンドで実行されているときに位置情報の更新を引き続き受信する場合は、まず必要な権限を追加してこの機能を有効にする必要があります。 Android では、 Android 10 ( API レベル 29 )以上を対象とする場合にのみ必要です。 アプリ AndroidManifest.xml
のファイルに次の権限を追加します。
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Android 14 以降をサポートする FOREGROUND_SERVICE_LOCATION
には、権限も必要です。
また、 Android API レベル 29 以上の Android デバイスでアプリをバックグラウンドで実行し続ける場合は、フォアグラウンドサービスまたは同等のサービスを開始する必要があります。 バックグラウンド位置情報を要求する Android では、フォアグラウンド位置情報の権限を要求するのとは異なることに注意してください。 詳細については、 Android のドキュメントを参照してください。 アプリ のポジショニング例 では、 Android 29 以降でのバックグラウンドポジショニングのサポート方法はまだ示されていません。
注
アプリが Android API レベル 28 以下を対象としている場合、前の「必要な権限を追加する」セクションで説明した権限がアプリによってすでに要求されている限り、バックグラウンドでの更新をサポートするために変更を加える必要はありません。
iOS では、アプリ Info.plist
のファイルに次のキーを追加することで、バックラウンド更新を有効にできます。
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>processing</string>
</array>
iOS バージョン 13.0 以降では、「処理」モードが必要です。 追加する場合は、次のものも必要です。
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
詳細については、 iOS のドキュメントを参照してください。
ユーザーに自動化を要求する必要があることに注意してください。 ユーザーに権限を要求する方法については、 [ 必要な権限を追加 ] セクションを参照してください。
自動化がクリアされると、すべての設定が完了します。 iOS デバイスで LocationEngine.setBackgroundLocationAllowed()
は、メソッドを使用してバックグラウンドで位置情報の更新を有効または無効にできます。 また、 iOS デバイスでは、メソッドを使用 LocationEngine.setBackgroundLocationIndicatorVisible()
して、アプリケーションのバックグラウンド位置情報インジケータの表示範囲を設定できます。
iOS デバイスの最終確認では、デバイスが停止しているときに、 LocationEngine.setPauseLocationUpdatesAutomatically()
メソッドに渡された false
位置情報の更新が一時停止しないようにします。
注
setBackgroundLocationAllowed()
と setBackgroundLocationIndicatorVisible()
は、アプリケーションでバックグラウンド位置情報フィーチャーが有効になっていない場合には、LocationEngineStatus.notAllowed
が戻ります。 それ以外の場合は 、LocationEngineStatus.ok
が返されます。
Android プラットフォームでは setBackgroundLocationAllowed()
、 setBackgroundLocationIndicatorVisible()
および setPauseLocationUpdatesAutomatically()
が LocationEngineStatus.notSupported
返されます。
AppLifecycleState
また、バックグラウンド更新が有効になっている場合は、を聴くことをお勧めします。
Android デバイスで位置情報オプションを指定します
Android デバイスをターゲットにしている場合に、場所の生成時に考慮するオプションをより細かく制御するには、 LocationOptions
オブジェクトを作成し、好みに合わせて設定してから、 startWithLocationOptions(locationOptions)
メソッドを呼び出してエンジンを開始します。
LocationOptions locationOptions = LocationOptions();
locationOptions.wifiPositioningOptions.enabled = true;
locationOptions.satellitePositioningOptions.enabled = true;
locationOptions.sensorOptions.enabled = false;
locationOptions.cellularPositioningOptions.enabled = false;
locationOptions.notificationOptions.smallestIntervalMilliseconds = 30000;
locationOptions.notificationOptions.desiredIntervalMilliseconds = 60000;
_locationEngine.startWithLocationOptions(locationOptions);
注
iOS plaftorms では startWithLocationOptions()
、が返さ LocationEngineStatus.notSupported
れます。
次の表に、使用可能 LocationAccuracy
なモードの概要、 LocationOptions
および Android での内部変換方法、 CLLocationAccuracy
および iOS でのモードへの内部変換方法を示します。
位置精度 | 位置情報オプション( Android ) | CLLocationAccuracy ( iOS ) |
Best_Available | cellularPositioningOptions.enabled=true satellitePositioningOptions.enabled=true wifiPositioningOptions.enabled=true sensorOptions.enabled=true notificationOptions.desired_interval_millisec =30000 (30s) notificationOptions.small_interval_millisec=1000 (11) | kCLLocationAccuracyBest |
NAVIGATION | cellularPositioningOptions.enabled=false satellitePositioningOptions.enabled=true wifiPositioningOptions.enabled=true sensorOptions.enabled=true notificationOptions.desired_interval_millisec =1000 (1s) notificationOptions.small_interval_millisec=1000 (11) | kCLLocationAccuracyBestForNavigation |
sub_meter_navigation | cellularPositioningOptions.enabled=false satellitePositioningOptions.enabled=true satellitePositioningOptions.hdEnabled=true wifiPositioningOptions.enabled=true sensorOptions.enabled=true notificationOptions.desired_interval_millisec =1000 (1s)notificationOptions.small_interval_millisec=1000 (1s) | 該当なし |
TENS_OF_METERS | cellularPositioningOptions.enabled=false satellitePositioningOptions.enabled=false wifiPositioningOptions.enabled=true sensorOptions.enabled=true notificationOptions.desired_interval_millisec =30000 (30s) notificationOptions.small_interval_millisec=1000 (1s) | kCLLocationAccuracyNearestTenMeters |
HUNDREDS_OF_METERS | cellularPositioningOptions.enabled=true satellitePositioningOptions.enabled=false wifiPositioningOptions.enabled=true sensorOptions.enabled=false notificationOptions.desired_interval_millisec =30000 (30s) notificationOptions.small_interval_millisec=1000 (11) | kCLLocationAccuracyHundredMeters |
KILOMETERS | cellularPositioningOptions.enabled=true satellitePositioningOptions.enabled=false wifiPositioningOptions.enabled=false sensorOptions.enabled=false notificationOptions.desired_interval_millisec =30000 (30s) notificationOptions.small_interval_millisec=1000 (11) | kCLLocationAccuracyThreeKilometers |
注
希望する間隔は LocationEngine
によって保証されないため、場所が多かれ少なかれ配信される可能性があります。一方、最小の間隔では、定義された値を超える頻度で場所が提供されないことが保証されます。
Android デバイスでのサブメーターナビゲーション
Android デバイスをターゲットにしている場合 、LocationEngine
with LocationAccuracy.subMeterNavigation
モードを開始すると HERE HD GNSS Positioning が有効になります。 HD GNSS(高解像度グローバルナビゲーション衛星システム)機能を使用すると、レーンアシスタンス、ターンバイターンガイダンス、拡張現実など、さまざまな用途に高解像度のポジショニングを行うことができます。 HD GNSS はクラウドベースのソリューションで、マスマーケットのデバイスが世界中でサブメートルの精度を達成できるようにします。
HD GNSS には、使用されている Android デバイスに特別な要件があります。 この機能が動作するには、 Android バージョンのデバイスが 12 ( API 31 )以上である必要があります。 具体的には、デバイスが以下をサポートしている必要があります。
- 生の GNSS 測定値
- GNSS キャリア位相測定( ADR )
- デュアル周波数 GNSS 受信機( L5 )
詳細については、Android のドキュメントも参照してください。
使用しているデバイスで上記の条件が満たされていることを確認する責任はユーザーにあります。 そうでない場合は、目的の精度レベルに達していない可能性があります。
上記の条件は、古いバージョンの一部の Android デバイスでも保持されます。 LocationAccuracy.SUB_METER_NAVIGATION
これらのバージョンの一部ではモードを正常に使用できますが、この操作は開発およびテストの目的でのみ行う必要があります。
従来の GNSS ソリューション(左)と HERE HD GNSS ソリューション(右)のグラウンドトラック精度の比較例。 この機能はデフォルトでは使用できませんが、個別にアクティブ化する必要があります。 HERE HD GNSS 補正データにアクセスするには、資格情報 が必要です。 詳細については、HEREにお問い合わせください。
注
LocationAccuracy.SUB_METER_NAVIGATION
モードを使用しても、どのような場合にも確実に使用されるわけではありませんが、他のポジショニングソースおよびテクノロジーにフォールバックする可能性があります。 この理由としては、デバイスに必要な機能がない、 GNSS 測定の品質が低い都市部と見なされる可能性のある環境、または資格情報 がこの機能で有効になっていない場合などが挙げられます。
Location
オブジェクト内に存在する horizontalAccuracyInMeters
フィールドは、「不確実性の半径」とも呼ばれ、68% の確率で真の地理座標が存在する可能性が高いエリアの推定値を提供します。これは、現在の位置の周囲にハローインジケータを描画するために使用されます。 下の図は、内側の緑色の円location.coordinates
に 、周囲の円を半径の精度の円horizontalAccuracyInMeters
として示し ています。 正確な地理座標は、精度円の内側(68%)または外側(32%)にあります。
図: 水平方向の不確実性と垂直方向の不確実性の半径。 同様に、高度の場合、 verticalAccuracyInMeters
値が10メートルの場合、実際の高度は 、 68%の確率で、高度-10mから高度+10mの範囲内にあると予想されます。 bearingAccuracyInDegrees
およびspeedAccuracyInMetersPerSecond
などの他の精度値も同じ規則に従います。不確実性が小さいほど精度が向上します。
注
Android デバイスで coordinates.altitude
は、 WGS 84 参照楕円体に関連して値が指定されます。 iOS デバイスで coordinates.altitude
は、その値は平均海面レベルを基準にして代わりに指定されます。
68% を超える確率で達成 (CEP68)
68% の確率 (CEP68) では不十分な場合、 99% の精度を達成できますか ? はい、次のとおりです。 与えられた円形誤差確率 (CEP) は自由度が 2 つのカイ (χ)2乗分布に続くため、次の式に基づいて望ましい確率を簡単に計算できます。
確率 | 不確実性の半径 |
50% | CEP50 = 0.78 x CEP68 |
60% | CEP60 = 0.90 x CEP68 |
70% | CEP70 = 1.03 x CEP68 |
80% | CEP80 = 1.19 x CEP68 |
90% | CEP90 = 1.42 x CEP68 |
95% | CEP95 = 1.62 x CEP68 |
99% | CEP99 = 2.01 x CEP68 |
上の表を使用して、マップ上のハローインジケータのさまざまな確率レベルを表示できます。 たとえば、水平方向の精度が 20 メートルの場合、半径のほぼ 2 倍の確率で 99 %を達成できます。 精度値は常に CEP68 として指定されます。つまり、次のことを意味します。
CEP99 = 2.01 x CEP68 = 2.01 x 20m = 40.2m
発見された場所の周囲に 40.2 メートルの半径を描画できるようになり ました。確率は 99% で、実際の場所はその円の内側にあります。 一方、半径 0 メートルの確率は 0% です。
法的要件
HERE SDK の位置情報機能を使用するには、前述のように、アプリケーションで HERE SDK の同意ダイアログを表示する必要があります。 ユーザーは、現在の承諾の決定を参照し、以前の承諾の決定を取り消すことができる必要があります。そうしないと、 HERE SDK の位置情報機能を使用できなくなり、代わりにプラットフォームの位置情報 API を参照する必要があります。
注
この要件は、現在 iOS にデータ収集がないため、 Android アプリケーションにのみ適用されます。 これは今後変更される可能性があります。
チュートリアル : 現在地を地図に表示
LocationIndicator
は 、マップ上のデバイスの現在位置を表すために使用されます。 インジケータが現在の位置の値で更新される前に、デフォルト Location
が設定されます。デフォルトは、最後に確認された場所、または最初の位置更新が到着する前にユーザが表示する必要がある場所です。 デフォルトでは、水平精度は半径horizontalAccuracyInMeters
のMapCircle
で表示されます。
static final GeoCoordinates _defaultGeoCoordinates = GeoCoordinates(52.530932, 13.384915);
LocationIndicator _locationIndicator;
void _addMyLocationToMap(Location myLocation) {
if (_locationIndicator != null) {
return;
}
_locationIndicator = LocationIndicator();
_locationIndicator!.isAccuracyVisualized = true;
_locationIndicator!.locationIndicatorStyle = LocationIndicatorIndicatorStyle.pedestrian;
_locationIndicator!.updateLocation(myLocation);
_locationIndicator!.enable(_hereMapController!);
MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, _cameraDistanceInMeters);
_hereMapController!.camera.lookAtPointWithMeasure(
myLocation.coordinates,
mapMeasureZoom,
);
setState(() {
_location = myLocation;
});
}
Location? location = _locationEngine.lastKnownLocation;
if (location == null) {
location = Location.withCoordinates(_defaultGeoCoordinates);
location.time = DateTime.now();
}
_addMyLocationToMap(location);
void _updateMyLocationOnMap(Location myLocation) {
if (_locationIndicator == null) {
return;
}
_locationIndicator?.updateLocation(myLocation);
_hereMapController?.camera.lookAtPoint(myLocation.coordinates);
setState(() {
_location = myLocation;
});
}
スクリーンショット: マップ上の現在の位置を示す位置情報インジケータ。 上記の実装に示されているように、updateLocation()
を呼び出して、Location
オブジェクトを位置情報インジケータに渡すことができます。 この例では、ユーザーの現在の位置を追跡することを目的としています。そのため、マップビューポートの中心位置も更新されます。