Documentation

Location

The Wikitude SDK does not provide a location strategy, which means that the location has to be provided to the SDK by using architectView.setLocation(latitude, longitude, altitude).

Management of the location is important in location based augmented reality applications. Depending on the use-case location is used via GPS or network and may be updated every second or once in a while. Although the SDKExamples project provides a basic implementation of a LocationProvider this is by far not the best location strategy available for Android.

Please use your own advanced location strategy implementation in case you have special requirements.

Example Location Strategy

The location strategy used by the sample app is the following:

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 );
                }
            }
        }
    }
}
Note: Make sure you have Location Permissions before calling onPause/onResume of the LocationProvider.

This can be used by the Activity containing the ArchitectView in the following way:

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();
    }
}