Start a new topic

setLocation: LocationService is not initialized

Hi there. Though I am sure I was doing everything as I shoud with regards to livecycle handling, I am getting setLocation: LocationService is not initialized all over the place. So, I fired up the provided SDK examples and guess what!


 E/ArchitectView: setLocation: LocationService is not initialized.

 E/ArchitectView: setLocation: LocationService is not initialized.

 E/ArchitectView: setLocation: LocationService is not initialized.

..


Samsung Galaxy S7 on Android 7


How to overcome this?


Best regards


1 person has this problem

If you need some sourcecode, here's are the relevant parts (assume premissions to Location and Camera have already been given in a previous SplashScreenActivity).


@ConfigPersistent
public class ARPresenter extends BasePresenter<ARView> {


private final GetPoisByCollectionId getPoisByCollectionId;
private final LoginManager loginManager;
private CompositeSubscription mapSubscriptions = Subscriptions.from();
private ArchitectView architectView;

private Subscription poisSubscription;
private List<Poi> pois;
private AtomicBoolean lockCamera = new AtomicBoolean(true);
private Subscription timerSubscription;

private AtomicBoolean architectViewLoadedSuccessfully = new AtomicBoolean(false);

@Inject
public ARPresenter(GetPoisByCollectionId getPoisByCollectionId, LoginManager loginManager, RxEventBus eventBus) {
super(eventBus, loginManager);
this.getPoisByCollectionId = getPoisByCollectionId;
this.loginManager = loginManager;
}

@Override
public void attachView(ARView view) {
super.attachView(view);
}

public void setupMaps(Integer poiCollectionId) {

getView().showInSnackbar("setting up Google-Maps™");

SupportMapFragment mapsFragment = getView().getMapsFragment();

new Handler(getView().getContext().getMainLooper()).post(() -> {

MapObservableProvider mapObservableProvider = new MapObservableProvider(mapsFragment);

mapSubscriptions
.add(mapObservableProvider
.getMapReadyObservable()
.subscribe(googleMap -> {
if (poiCollectionId != null) {
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
loadPois(poiCollectionId);
}
}, onError("error setting up Google Maps")));

mapSubscriptions
.add(mapObservableProvider.getMapLongClickObservable()
.subscribe(
onMapInteraction(),
onError("error setting up Google Maps")));

mapSubscriptions
.add(mapObservableProvider.getMapClickObservable()
.subscribe(
onMapInteraction(),
onError("error setting up Google Maps")));

mapSubscriptions
.add(mapObservableProvider.getCameraMoveObservable()
.throttleFirst(500, TimeUnit.MILLISECONDS)
.subscribe(
onMapInteraction(),
onError("error setting up Google Maps")));

mapSubscriptions
.add(mapObservableProvider.getMarkerClickObservable()
.subscribe(marker -> {
try {
Integer poiId = (Integer) marker.getTag();
getView().onPoiClicked(poiId);
} catch (Exception e) {
Timber.e(e, "Marker has no POI attached");
}
}));
});
}

@NonNull
private <T> Action1<T> onMapInteraction() {
return t -> {
lockCamera.set(false);
Timber.d("camera unlocked");
unsubscribe(timerSubscription);
timerSubscription = Observable.timer(8, TimeUnit.SECONDS).subscribe(aLong -> lockCamera.set(true));
};
}

public void setupWikitude() {

getView().showInSnackbar("setting up Wikitude™");

if (BuildConfig.DEBUG) {
if ((getView().getContext().getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
WebView.setWebContentsDebuggingEnabled(true);
}
}

ArchitectStartupConfiguration startupConfiguration = new ArchitectStartupConfiguration();
startupConfiguration.setLicenseKey(BuildConfig.WIKITUDE_SDK_KEY);
startupConfiguration.setFeatures(ArchitectView.getSupportedFeaturesForDevice(getView().getContext()));
startupConfiguration.setCameraResolution(CameraSettings.CameraResolution.SD_640x480);


if (architectView == null) {

architectView = getView().getArchitectView();
architectView.onCreate(startupConfiguration);

RxArchitectView
.urlChange(architectView)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
this::parseWikitudeUrl,
onError("Error reading Wikitude WebView URL"));
}
}

public void onPostCreate(Integer poiCollectionId) {

if (architectView != null && !architectViewLoadedSuccessfully.get()) {

architectView.onPostCreate();

RxArchitectView
.load(architectView)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.debounce(2, TimeUnit.SECONDS)
.subscribe(
successMessage -> {
setupMaps(poiCollectionId);
architectView.setCullingDistance(BuildConfig.CULLING_DISTANCE_METER);
architectView.addArchitectJavaScriptInterfaceListener(jsonObject -> {
Timber.d(jsonObject.toString());
});
architectViewLoadedSuccessfully.set(true);
},
onError("Error loading ArchitectView"));
}
}

public void resumeWikitude() {
if (this.architectView != null) {
this.architectView.onResume();
}
}

public void pauseWikitude() {
if (this.architectView != null && architectViewLoadedSuccessfully.get()) {
this.architectView.onPause();
}
architectViewLoadedSuccessfully.set(false);
}

private void parseWikitudeUrl(String url) {

Uri uri = Uri.parse(url);
if ("markerselected".equalsIgnoreCase(uri.getHost())) {
Integer id = Integer.valueOf(uri.getQueryParameter("id"));
String title = uri.getQueryParameter("title");
String description = uri.getQueryParameter("description");
String text = String.format("Poi '%s' with id %s clicked", title, id);
getView().onPoiClicked(id);
}
}


private void showPoisInArchitectView(List<Poi> pois) {

String ATTR_ID = "id";
String ATTR_NAME = "title";
String ATTR_DESCRIPTION = "description";
String ATTR_LATITUDE = "latitude";
String ATTR_LONGITUDE = "longitude";
String ATTR_ALTITUDE = "altitude";

JSONArray poiArray = new JSONArray();


for (int i = 0; i < pois.size(); i++) {
final HashMap<String, String> poiInformation = new HashMap<>();
poiInformation.put(ATTR_ID, String.valueOf(pois.get(i).getId()));
poiInformation.put(ATTR_NAME, pois.get(i).getName());
poiInformation.put(ATTR_DESCRIPTION, "");

double[] poiLocationLatLon = getRandomLatLonNearby(52.1784615, 7.0343582);
float latitude = pois.get(i).getLatitude();
float longitude = pois.get(i).getLongitude();
poiInformation.put(ATTR_LATITUDE, String.valueOf(latitude));
poiInformation.put(ATTR_LONGITUDE, String.valueOf(longitude));
final float UNKNOWN_ALTITUDE = -32768f; // equals "AR.CONST.UNKNOWN_ALTITUDE" in JavaScript (compare AR.GeoLocation specification)
poiInformation.put(ATTR_ALTITUDE, String.valueOf(UNKNOWN_ALTITUDE));
poiArray.put(new JSONObject(poiInformation));
}

callJavaScript("World.loadPoisFromJsonData", new String[]{poiArray.toString()});
}

private static double[] getRandomLatLonNearby(final double lat, final double lon) {
return new double[]{lat + Math.random() / 10 - 0.05, lon + Math.random() / 10 - 0.05};
}

public void callJavaScript(final String methodName, final String[] arguments) {
StringBuilder argumentsString = new StringBuilder("");
for (int i = 0; i < arguments.length; i++) {
argumentsString.append(arguments[i]);
if (i < arguments.length - 1) {
argumentsString.append(", ");
}
}

if (getView().getArchitectView() != null) {
String js = (methodName + "( " + argumentsString.toString() + " );");
getView().getArchitectView().callJavascript(js);
}
}

public void loadPois(int poiCollectionId) {
getView().showInSnackbar("loading POI's");
getPoisByCollectionId.setPoiCollectionId(poiCollectionId);

unsubscribe(poisSubscription);
poisSubscription = getPoisByCollectionId
.fetch()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(pois -> {
getView().showProgress(false);
this.pois = pois;
showPoisOnMap(pois);
showPoisInArchitectView(pois);
}, onError("error loading PoiCollections"));
}

private void showPoisOnMap(List<Poi> pois) {

stream(pois).forEach(poi -> getView().getMapsFragment().getMapAsync(googleMap -> {
LatLng latLng = new LatLng(poi.getLatitude(), poi.getLongitude());
MarkerOptions marker = new MarkerOptions()
.title(poi.getName())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.position(latLng);

Marker m = googleMap.addMarker(marker);
m.setTag(poi.getId());
}));
}

@Override
public void detachView() {
super.detachView();
if (architectView != null) {
architectView.clearCache();
architectView.onDestroy();
}

unsubscribe(poisSubscription);
unsubscribe(timerSubscription);
}

@Override
protected void onLocationUpdated(Location location) {

super.onLocationUpdated(location);

GeomagneticField field = new GeomagneticField(
(float) location.getLatitude(),
(float) location.getLongitude(),
(float) location.getAltitude(),
System.currentTimeMillis()
);

// getDeclination returns degrees

if (getView() != null) {
SupportMapFragment mapsFragment = getView().getMapsFragment();
if (null != mapsFragment) {
mapsFragment.getMapAsync(googleMap -> {
if (lockCamera.get()) {
Timber.d("camera locked");
CameraPosition camPos = CameraPosition
.builder(googleMap.getCameraPosition())
.target(new LatLng(location.getLatitude(), location.getLongitude()))
.zoom(15.0f)
.tilt(30.0f)
.build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(camPos));
}
});

if (architectView == null || !architectViewLoadedSuccessfully.get()) {
return;
}

if (location.hasAltitude() && location.hasAccuracy() && location.getAccuracy() < 7) {
architectView.setLocation(location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getAccuracy());
} else {
architectView.setLocation(location.getLatitude(), location.getLongitude(), location.hasAccuracy() ? location.getAccuracy() : 1000);
}
}
}
}

public void onUserPhoto(File file) throws IOException {
Bitmap bitmap = BitmapUtils.fromMediaStorage(getView().getContext(), Uri.fromFile(file));
UserImage userImage = new UserImage();
userImage.setTitle(loginManager.getCachedUsername() + "_" + new Date().toString());
// TODO: send to remote
//getBitmap(getView().getContext().getContentResolver(), file);

}

public List<Poi> getPois() {
return pois;
}

public void deselectCurrentMarker() {
callJavaScript("World.deselectCurrentMarker", new String[0]);
}

public void onUserPhoto(Bitmap imageBitmap) {
System.out.println("geil atze");
}

public void onUserPhotos(List<File> imageFiles) {
getView().showInSnackbar("Saving your image...");
}

public void onUserText(String message) {
getView().showInSnackbar("Saving your note...");
}
}


setupWikitude() is being invoked in onCreate() and onPostCreate() thus in onPostCreate() of the ARActivity. Further, this is the Rx code for RxArchitectView and ArchitectViewLoadedOnSubscribed()


public class RxArchitectView {

public static Observable<String> load(ArchitectView architectView) {
try {
Observable<String> stringObservable = Observable.create(new ArchitectViewLoadedOnSubscribe(architectView));
architectView.load(Constants.Wikitude.ARCHITECT_WORLD_URL);
return stringObservable;
} catch (IOException e) {
String name = Thread.currentThread().getName();
Timber.d(name);
return Observable.error(e);
}
}

public static Observable<String> urlChange(ArchitectView architectView) {
return Observable.create(new ArchitectViewUrlChangeOnSubscribe(architectView));
}
}



public class ArchitectViewLoadedOnSubscribe implements Observable.OnSubscribe<String> {

final ArchitectView architectView;

public ArchitectViewLoadedOnSubscribe(ArchitectView architectView) {
this.architectView = architectView;
}

@Override
public void call(Subscriber<? super String> subscriber) {

ArchitectView.ArchitectWorldLoadedListener listener = new ArchitectView.ArchitectWorldLoadedListener() {
@Override
public void worldWasLoaded(String message) {
if (!TextUtils.isEmpty(message) && !subscriber.isUnsubscribed()) {
subscriber.onNext(message);
}
}

@Override
public void worldLoadFailed(int i, String s, String s1) {
subscriber.onError(new ArchitectView.ArchitectInitializeException(s + " - " + s1 + " - " + i) {
@Override
public String getMessage() {
return super.getMessage();
}
});
}
};

subscriber.add(new MainThreadSubscription() {
@Override
protected void onUnsubscribe() {
architectView.registerWorldLoadedListener(null);
}
});

architectView.registerWorldLoadedListener(listener);
}
}

Hi. 

I attached the regarding source code underneath my initial post. The inital post took 15 minutes to 'check'. The sources were posted 5 hours ago. Found any spam in it?

Hi Simon!


So you also tried the SDK samples and see the same logs? Samples using location are based on same LocationProvider implementation. I assume that the samples work as expected, right? If that's the case and you still see the log, you can gracefully ignore it and I will create a ticket to get rid of this entry in an upcoming release.


Please also try very latest SDK Samples from download section.


Best regards,
Andi

I am having the same issue , It was working for one day then started getting the same error.


Thanks and Regards,


Hey there. I don't know your exact issue but let me tell you, mind the lifecycle of your Activity/Fragment and the one of Wikitude. I will open-source our project soon so you can take a peak. Hang in there, Wikitude is a beach when it comes to managing the lifecycle, bring a towel.
Login or Signup to post a comment