ロケーション
Wikitude SDKはロケーションストラテジを提供していません。このため、architectView.setLocation(latitude, longitude, altitude)
メソッドを使用して、緯度、経度、高度をSDKに渡す必要があります。
ロケーションの管理は、ロケーションベースの拡張現実アプリケーションでは重要になります。 利用する場所に応じて、GPSまたはネットワーク経由で使用され、1秒ごとに更新、あるいは1度に更新されることがあります。 SDKExamplesプロジェクトでは、LocationProvider
の基本的な実装が提供されていますが、これはAndroidで利用できる最適なロケーションストラテジではありません。
特別な要件がある場合は、独自の高度な位置情報ストラテジの実装を行ってください。
ロケーションストラテジの例
サンプルアプリケーションで使用されるロケーションストラテジは次のとおりです。:
public class LocationProvider{
/** location listener called on each location update */
private final LocationListener locationListener;
/** system's locationManager allowing access to GPS / Network position */
private final LocationManager locationManager;
/** location updates should fire approximately every second */
private static final int LOCATION_UPDATE_MIN_TIME_GPS = 1000;
/** location updates should fire, even if last signal is same than current one (0m distance to last location is OK) */
private static final int LOCATION_UPDATE_DISTANCE_GPS = 0;
/** location updates should fire approximately every second */
private static final int LOCATION_UPDATE_MIN_TIME_NW = 1000;
/** location updates should fire, even if last signal is same than current one (0m distance to last location is OK) */
private static final int LOCATION_UPDATE_DISTANCE_NW = 0;
/** to faster access location, even use 10 minute old locations on start-up */
private static final int LOCATION_OUTDATED_WHEN_OLDER_MS = 1000 * 60 * 10;
/** is gpsProvider and networkProvider enabled in system settings */
private boolean gpsProviderEnabled, networkProviderEnabled;
public LocationProvider( final Context context, LocationListener locationListener ) {
super();
this.locationManager = (LocationManager)context.getSystemService( Context.LOCATION_SERVICE );
this.locationListener = locationListener;
this.gpsProviderEnabled = this.locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER );
this.networkProviderEnabled = this.locationManager.isProviderEnabled( LocationManager.NETWORK_PROVIDER );
}
public void onPause() {
if ( this.locationListener != null && this.locationManager != null && (this.gpsProviderEnabled || this.networkProviderEnabled) ) {
this.locationManager.removeUpdates( this.locationListener );
}
}
public void onResume() {
if ( this.locationManager != null && this.locationListener != null ) {
// check which providers are available are available
this.gpsProviderEnabled = this.locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER );
this.networkProviderEnabled = this.locationManager.isProviderEnabled( LocationManager.NETWORK_PROVIDER );
/** is GPS provider enabled? */
if ( this.gpsProviderEnabled ) {
final Location lastKnownGPSLocation = this.locationManager.getLastKnownLocation( LocationManager.GPS_PROVIDER );
if ( lastKnownGPSLocation != null && lastKnownGPSLocation.getTime() > System.currentTimeMillis() - LOCATION_OUTDATED_WHEN_OLDER_MS ) {
locationListener.onLocationChanged( lastKnownGPSLocation );
}
if (locationManager.getProvider(LocationManager.GPS_PROVIDER)!=null) {
this.locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_UPDATE_MIN_TIME_GPS, LOCATION_UPDATE_DISTANCE_GPS, this.locationListener );
}
}
/** is Network / WiFi positioning provider available? */
if ( this.networkProviderEnabled ) {
final Location lastKnownNWLocation = this.locationManager.getLastKnownLocation( LocationManager.NETWORK_PROVIDER );
if ( lastKnownNWLocation != null && lastKnownNWLocation.getTime() > System.currentTimeMillis() - LOCATION_OUTDATED_WHEN_OLDER_MS ) {
locationListener.onLocationChanged( lastKnownNWLocation );
}
if (locationManager.getProvider(LocationManager.NETWORK_PROVIDER)!=null) {
this.locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, LOCATION_UPDATE_MIN_TIME_NW, LOCATION_UPDATE_DISTANCE_NW, this.locationListener );
}
}
}
}
}
注:LocationProviderのonPause / onResumeを呼び出す前に、ロケーション権限があることを確認してください。
これはArchitectViewを含むアクティビティで次のように使用できます。
public class SampleActivity extends Activity {
private ArchitectView architectView;
private LocationProvider locationProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_cam);
architectView = (ArchitectView)this.findViewById( R.id.architectView );
final ArchitectStartupConfiguration config = new ArchitectStartupConfiguration();
config.setFeatures(ArchitectStartupConfiguration.Features.Geo);
config.setLicenseKey( "YOUR-LICENCE-KEY" );
architectView.onCreate( config );
locationProvider = new LocationProvider(this, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location!=null && SampleActivity.this.architectView != null ) {
// check if location has altitude at certain accuracy level & call right architect method (the one with altitude information)
if ( location.hasAltitude() && location.hasAccuracy() && location.getAccuracy()<7) {
SampleActivity.this.architectView.setLocation( location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getAccuracy() );
} else {
SampleActivity.this.architectView.setLocation( location.getLatitude(), location.getLongitude(), location.hasAccuracy() ? location.getAccuracy() : 1000 );
}
}
}
@Override public void onStatusChanged(String s, int i, Bundle bundle) {}
@Override public void onProviderEnabled(String s) {}
@Override public void onProviderDisabled(String s) {}
});
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
architectView.onPostCreate();
try {
architectView.load( "YOUR-AR-EXPERIENCE" );
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
architectView.onResume();
// start location updates
locationProvider.onResume();
}
@Override
protected void onPause() {
super.onPause();
architectView.onPause();
// stop location updates
locationProvider.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
architectView.onDestroy();
}
}