I am developing an Android application using skobbler/telenav SDK also known as SKMaps. I am currently implementing a simple gps navigation system using SKRouteManager and SKNavigation manager and the corresponding Listeners. So far I have been able to set the destination for my navigation by geocoding postcodes into gps locations using the google api. I also have alternative routes and the onReRoutingStarted() event of the SKNavigationListener is working right. However, I have a problem with onDestinationReached() - it seems like it does not get called when I reach my destination so my navigation does not stop. So if I keep driving and pass the destination point the app starts rerouting me again. Is there an issue with the onDestinationReached() or any special requirements when implementing it?
I thought it should work because it successfully calculates the route in the first place so it should know the destination point and I shouldnt have to specify it in any other way. But the method does not get called by the app when I reach the end of the route.
I have also encountered another issue with the SKNavigationListener events - onUpdateNavigationState(SKNavigationState navigationState). Inside the method I am trying to obtain some of the information the SKNavigationState object should be able to provide me with. The problems are as follows:
Eclipse cannot recognise the method getDistanceToDestination() - acts as if it is not defined inside the class SKNavigationState.
getCurrentAdviceCurrentStreetName() returns null
As far as I understand getCurrentAdviceDistanceToAdvice() should give me the distance to the point where I will receive another advice and getCurrentAdviceDistanceToDestination() should give me the remaining distance to the end point of the route. Both methods are supposed to return the distance in meters but they provide me with some really large numbers (more than a billion) when my route is only 5 kilometers long. Also, sometimes they return 0.
The onUpdateNavigationState(SKNavigationState navigation state) is supposed to get called multiple times while following the route and every time provide me with new information about the state of my navigation. It does get called multiple times but when I use the above methods they keep returning the same values (if I restart the application the values change but during a single test they give me the same values).
If anyone has any clue what could be going wrong. It is really confusing because I can successfully get the current speed from the SKNavigationState object using getCurrentSpeed(). But somehow some of the methods seem to not exist and others return values that dont make sense.
This issue was a bug on the 2.0.2 SDK version - it was fixed in vs 2.1.0 (which should be out on the 30'th of June 2014)
Related
I am using the HERE Android SDK embedded in a QT application, and am trying to do turn by turn directions simulated, but without a map display. There is no Map or MapFragment in my app, I'm using the MapEngine and NavigationManager directly. And I am initializing the map engine on the main UI thread, as that is recommended (not sure if that could be an issue here).
I am able to initialize the map engine, create the route and dump it successfully. However, when I use NavigationManager to simulate the route, I can see navigation movement (the coordinates in position updates progressing). However, I have ManeuverEventListeners and NewInstructionEventListeners, and they are never called.
And in my position listener, if I call getNextManeuverDistance() or getETA() I get error responses. All other functions had success, and the simulated navigation will complete eventually (at the expected time) but without ever delivering any instructions.
I have the same code working fine in a sample app, but running in the QT framework I'm never getting valid distances or maneuvers. In the API reference it says getNextManeuver() will return null (and get distance returns MAX_INT) if the next maneuver is not available yet. What can be causing this?
Is it valid to run this in an app without a Map nor a MapFragment? Any ideas why NavigateManager simulate would act this way?
Yes, I eventually figured out that the map data must be manually preloaded. Seems that calculating the route is not enough, and the data fetching is normally done by the map view, and the navigation manager is just waiting for the map data.
In my case, as soon as I have a calculated route I start the mMapDataPrefetcher.fetchMapData(route,radius), and then immediately start the mNavigationManager.simulate(route,speed). The navigation is a little wonky until the map data is loaded, but starts responding immediately after the map loading is complete. The loading can be slow in some of my testing, not sure why. But in frequent uses, the map data is often already present, so works better in that case.
I'm not sure what a good radius is; I tried 500m and the call failed; 2000m is working for me right now.
See the pages here:
https://developer.here.com/documentation/android-premium/topics/map-data.html
https://developer.here.com/documentation/android-premium/topics/maps-offline.html
These features are described as beta, so I'm not sure if there is any way to do this in a supported, production fashion.
This is the call that I make:
https://maps.googleapis.com/maps/api/directions/json?alternatives=true&key=my_key&origin=52.370060,4.925040&destination=52.37913,4.90027&departure_time=1518168706&mode=transit
I This route, which should have atleast 3 metro's and some buses in between them, should find me results.
This is what I send as the departure_time to get that value:
(System.currentTimeMillis() / 1000
And sometimes it works, sometimes no. I tried using the same + 30 (adding 30 seconds to current time) but, again, sometimes I get results, sometimes just ZERO_RESULTS. Why?
I noticed that if I set the time to 5 minutes in the past, it works. but I need it to start at this moment. This makes no sense, why would the call return me results for the past, but not future, for planning
I am afraid your questions is a bit broad since the understanding of how google works internally is a mistery for most mortals, but there is a few cases where you can have zero_results.
The first one is that you use times that are already in the pasts. so always make sure the epoch time you use has not already passed.
Another could be that in the moment you requested the directions, there are no posible routes for your desire destinations, since google collects data from other sources like Live Traffic(for driving), etc.
What I found is that if this issue persist (that you keep getting zero_results) for a specific directions could be actually a Bug of the API, and you can report it in the issue tracker https://issuetracker.google.com/ since I found reported/accepted Bugs (like https://issuetracker.google.com/issues/63884989) related with your issue.
If I found more info I will update this answer.
I'm using HERE SDK trial and I want to ask that RealisticViewListener and LaneInformationListener works with trial license? Because I have registered listeners but I don't get any event.
navigationManager.addLaneInformationListener(new WeakReference<>(laneInformationListener));
navigationManager.setRealisticViewMode(NavigationManager.RealisticViewMode.DAY);
navigationManager.addRealisticViewAspectRatio(NavigationManager.AspectRatio.AR_4x3);
navigationManager.addRealisticViewListener(new WeakReference<NavigationManager.RealisticViewListener>(realisticViewListener));
Both features are available in the trial (as well as all other features). Your implementation looks correct, but it will be hard to determine where things go wrong without seeing more code.
Also, please be aware that in rare cases there is simply no lane- or signposts information available, e.g. the callback only occurs when the user has arrived at a point in the route where lane information is available such as before a highway exit.
I suggest to try out the SDK navigation example on GitHub and hook your listeners in from there to see how it works. You can also start navigation simulation (if you are unsure if your local area has enough data):
// if user wants to start simulation, submit calculated route
// and a simulation speed in meters per second
error = navigationManager.simulate(route, 60);
In my app I have a Service which receives location updates and stores them to a database. I also have a Fragment which displays a MapView and a PolyLine of all recorded waypoints from the database.
During recording, the Service notifies the Fragment about new waypoints so the Fragment can update the PolyLine. The problem is that when the user navigates away from the app the app the Service keeps recording waypoints to the database, but now the Fragment doesn't get updated since the Fragment is paused. So in onResume I create a new PolyLine, read all the waypoints in the database and add them to the database.
This is all working fine, but it doesn't really feel like it's optimal from a performance perspective to create a new PolyLine and re-add all the waypoints (there could be thousands!). I guess I could just re-add any new waypoints that are not already in the PolyLine, but I wanted to see if anyone here has an alternate solution? Is there any way to keep the Fragment "alive" and updating its PolyLine even when the app is in the background (as long as the service is running)? Or is there a better way to do this?
Recreating the polyline is probably inevitable, but here are some things you should think about doing if performance becomes an issue:
Put a time limit. When recreating the polyline, only fetch the data in the last hour or day (test and you'll be able to determine the best value here), and offer an option to extend that period. This will make it more understood by the user that the data needs some time to load, and that the app will use more resources.
Aggregate the data while saving them. This should reduce the disk space used to save the points in the database (very important for low end devices) and improve on the performance when rebuilding the activity.. These are some tips for what you can do to reduce the number:
Check 2 points behind and see if they are a straight line. If so, delete the middle one. That should remove a lot of data recorded when the user is in a car or walking a long distance
Check if the last set of points (5 or more) are in the same area, that way you can get rid of a lot of data. So if a user is just waling in his home or workplace, you can just save one point for that without loosing too much data, which shouldn't really be a problem in most (99%) of the applications.
I'm using indoorAtlas SDK. I already succed to show current location and floorplan using indoorAtlas. But it has some weird result.
If i'm inside building that i listed the floorplanid and venue id, it gives the correct current location. But when i'm outside that building and i'm trying to locate current location it gives the result in the floorplan map but it gives some random location.
Is there any way to give some notification or action that i'm outside in area that i'm listed floorplanid and venueid ?
In current SDK there is nothing that would give you straight answer to your question. I'd say that your best tools at the moment are the getUncertainty() -method in returned location update (ServiceState -class) combined with platform locations. Experiment with uncertainty value (radius in meters) to see when it would be best to start trusting platform locations over IndoorAtlas's indoor locations and to conclude that user has exited the building. In a more advanced version, when moving towards the edges of your floor plan (or better yet towards the exits) you could be more sure that transition (in->out, out->in) is likely to take place.
You could also combine this logic with geofences (http://developer.android.com/reference/com/google/android/gms/location/GeofencingApi.html) in one or more ways. E.g. use geofence as an indication that IndoorAtlas services should be turned on as user may enter a building and when entered, dynamically create a larger geofence as a safeguard to help your algorithm to detect that user has exited building and IndoorAtlas service can be turned off.
Hope this helps to find your solution.