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


2 people have this problem

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.

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


Thanks and Regards,


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

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?

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);
}
}
Login or Signup to post a comment