Pretty basic MapView crashes on Android, glitches a little on Iphone

@Ksan, it seems that on Android, we need to use some timer before calling some of the map api. As for pin that sometime were offset, this is a bug with some Android version only. Corona was never able to replicate this on their side. On our Galaxy s3 we can reproduce any time bad marker position.

I have remove useless code from our app and show you how we deal with marker. I don’t know if this what you are looking for. If not, ask, we have been working with map forever :wink:

– ************************************************************************

– Update all pins in our map

– ************************************************************************

local function _updatePins()

    if scene.googleMap then

        

        – We always center the map based on our first visible pin in our table

        scene.googleMap:setCenter( .latitude, .longitude )

        

        – our temporary marker lookup table

        scene.googleMarkerTable = {}

        

        – method called when a marker is click on

        local function markerListener(event)          

            classStoryboard.gotoScene( “viewMarkerItem”, { params = { markerItem = scene.googleMarkerTable[event.markerId] } } )

        end

        – Iterate the tabledata

        for itrMarker = 1, #tableData do

                         

            local markerOptTbl = {

                listener = markerListener, 

                }

                

            local item = tableData[itrMarker]

            local result, errorMessage = scene.googleMap:addMarker( item.latitude, item.longitude, markerOptTbl )

            if result then

                scene.googleMarkerTable[result] = tableData[itrMarker]

            end

        end

    end

    

end

– ************************************************************************

– Dispatch the update all pins

– ************************************************************************

function scene:updatePins()

    if scene.googleMap then

        scene.googleMap:removeAllMarkers()

        scene.googleMarkerTable = nil

        

        – On Androit only, it seems that we must introduce a delay between

        – calling removeAllMarkers and adding new one.

        timer.performWithDelay( gGlobalVar.addMarkerDelay, _updatePins )

    end

end

– ************************************************************************

– Create the map view, center the map and adjust the zoom

– ************************************************************************

function scene:createMapView()

    

    scene.googleMap = native.newMapView( x, y, w, h )

  

    if scene.googleMap then

        scene.googleMap.anchorX = 0

        scene.googleMap.anchorY = 0

        scene.googleMap.mapType = “standard”

        

        local gpsMap = gGps

        scene.googleMap:setCenter( gpsMap.regCenterLat, gpsMap.regCenterLon )

        scene.googleMap:setRegion( gpsMap.regCenterLat, gpsMap.regCenterLon, 0.1, 0.1, false)

    end

end

Hi @nmichaud, thank you so much for sharing your code. 

I am particularly interested in your marker touch listener 

 -- method called when a marker is click on local function markerListener(event) classStoryboard.gotoScene( "viewMarkerItem", { params = { markerItem = scene.googleMarkerTable[event.markerId] } } ) end

I am doing something very similar but noticing a lot of irregular behavior. Please see my thread on this for more detail : 

http://forums.coronalabs.com/topic/44906-mapview-marker-listener-is-very-inconsistent-and-un-reliable-any-ways-to-improve-this/?hl=mapview

Particularly, I see that sometimes you get the listener trigger on first tap, especially if you tap on the lower part of the marker and sometimes first tap brings the bubble and you need to tap the bubble to get the listener triggered (preferred behavior). I don’t see any precaution against this in your listener. Do you have another alternate solution or did this issue not surface during your testing?

Thanks once again for sharing and apologies for taking this thread offtopic

You are bringing something that hurt us badly. The Corona implementation of Google marker is quite weak in my opinion. What you are expecting cannot be done unfortunately. Here is what we discover during our initial implementation.

case 1: If in the option table you only define a callback. It will work as expected. Corona will call your callback when you tap the pin. Which is expected.

case 2: If you want to display the Google bubble, you must add the Title/Subtitle in the option table. In this case, we would expect that our callback is only called when we click on the bubble! but NO :frowning: The callback is always called when you click on the marker. Clicking on the bubble has no effect in our test. 

This is why that in our code, when a marker is click on we directly go to another page. It is not nice and it is not the best workflow but we had no choice for the time being. We have asked for a better implementation and we are waiting from them to enhance this feature to match a normal workflow and user expectation. We should be able to customize the bubble and put a nice button into it.

We should unite to have Corona fix this as in my opinion this is not good at all.

I completely agree with you. As expressed in my other thread the implementation is very weak and inconsistent to the point that the bubbles are not usable as they are.

In my implementation the bubbles are essential. There are 100+ markers which are all points of interest and people will go tapping on the markers at first to see the bubbles and if they wish to explore further they will tap on the bubbles to get to the detail. Going from marker direct to detail is not that usable. Just to let you know I managed to get this behavior in a little convoluted way. Counting taps and ignoring first tap but going to the detail on second tap does the trick although in a very crude way. Let me know if you wish to see this code although I warn you it is pretty silly.

Meanwhile the IOS and Android behavior is not consistent in how the taps in empty spots are handled. On IOS a tap in empty spot of the map closes all bubbles which is a good outcome for me. On Android when you tap on an empty spot nothing happens. The bubbles are not closed until you tap the X on them. The X is an Android only feature… 

I sincerely hope that Corona Labs does improve the mapView in future updates. Currently it is feature incomplete and buggy. 

I would be very interested to see how you did manage to do that if you are willing to share that code. 

Sure. Here it is. Basically I keep track of which marker is tapped last and how many times it was tapped in 2 global variables. If the same marker is tapped 2 times (or more) I jump to the detail view. This way I find that I can show the bubble but there are inconsistencies in this implementation as well. Maybe you can improve it if you like it. Good luck. 

PS. Ignore some additional / unused variables. I’ve been trying lots of things in there. 

local markerTapped = false local markerId local markersTable = {} local chosenMarker local markerTapCount = 0 local currentMarkerID = nil local function markerListener(event) markerId = event.markerId if currentMarkerID ~= markerId then currentMarkerID = markerId markerTapCount = 0 end markerTapCount = markerTapCount + 1 if markersTable[markerId] and markerTapCount \>= 2 then chosenMarker = markersTable[markerId].landmarkID local options = { effect = "slideLeft", isModal=true, params = { var1 = chosenMarker } } storyboard.gotoScene( "scn\_landmark\_details", options ) end end

Thanks we will give it a try and give you some feedback. But quick question. By looking at the code, it is when you click a second time on the same marker that you will go to your scene ? Clicking on the bubble itself as no effect, right ?

Clicking the bubble triggers the listener for me. At least on IOS. This is on 2187 as of today. No guarantees what tomorrow might hold for us!   :wink:

Edit : cleaned up the code a little above.

Edit 2 : the length of the tap on bubble and the marker seem to have a different effect on the listener. A quick peck vs a longer tap and release. Experiment to see how it works on your side. 

Ok, we will try it under iOS and will get back to you soon

No, I don’t make notes manually when filing a bug. I trust the team got the bug. (Or a lot of time and my test info has been lost.)

It would be great if you have found a workaround, but I think you have to set it up to work repeatedly and I suspect you may find that waiting doesn’t remove the bug. At least when I tested I would have it working for a few taps and thinking I fixed it. You need to zoom in/out to see the coordinate systems mismatch.

Just some FYI: I’m seeing the same issues with disappearing android map markers. It definitely is related to two calls - setMapRegion (changing the map view area, which causes google maps to load new map textures - which introduces a delay in drawing the new map), and in the removeAllMarkers call.

If you make an addMarker call too soon after either of those calls on android, you run a good chance of no marker appearing on the display. You may also run into issues (when the timing is close, but not quite good enough), where markers do appear, but are malformed in some way, such as zoomed up (and clipped, so you see a large 1/4 of a marker), or even “ghost” looking (as if the alpha is at 0.05 or something). I’m guessing that when they aren’t there at all, it’s probably a variation of one of these two visual edge cases – ie; when it’s missing, it’s totally at the wrong scale and only transparent pixels are showing from the markers top left corner, or it’s alpha is messed up.

In any case, I’m seeing this bug pretty consistently on the galaxy S3 running 4.3. If the time between the removeAll (or a big view change using setMapRegion), and addMarker is less than 500ms, after a few cycles changing maps/removing markers, it’s messed up - no markers/malformed markers. Delays of 750ms or more, it works better / more consistently.  (This may be related to google maps code having to contact the google server to get new map info, but the corona code moves ahead adding markers before google changes the map properties??)

This in on WiFi. The delay has to be even longer over the cell net :frowning:

I’ll check with engineering and see if it’s possible to add a call back function to the native.newMap() API.  Seems that you need to know when it’s complete to start adding things. 

Rob

That sounds like it would work for me, or:

  • if the SDK buffered the requests, and processed them after the map finished… (difficult no doubt)

  • or if the sdk kept a local copy of the apps requested new mapView area, so it could get it’s newMarker positions/scales correct while google does it’s thing… (presuming something along those lines is the problem) This might not be so hard…

iOS works well, but I’m guessing they handle a lot of the map data locally (the view area for instance), and modify it there, so there’s no timing issue.

That would be amazing! Thank you very much for your follow-up. We are literally shooting in the dark not knowing when map loading is complete. 

After talking to Engineering about this, while it’s possible to have an onComplete type features, they don’t believe this will help.  We already queue actions to Google.  In simple terms, we don’t add the map points until the map is loaded.  They have seen this behavior in the native maps app and it seems to be a rendering issue on the Google side.  Zooming in and out seems to solve it.  You might be able to simulate this using the setRegion() call. 

Rob

I think onComplete for map loading would help in other ways. It would allow us to be offer better user experience. Same with webViews. We need to know when loading has ended ideally.

@ksan, we have been busy with our new version and I did not have time to try it yet. I will do it as soon as possible :slight_smile:

Sure thing. Not to worry. I will look forward to hearing of your impressions. Either way the current mapView implementation by Corona Labs leave a lot to be desired. I hope they have a chance to revisit this API soon to fix existing bugs and implement many missing features. 

How did it work for you? Any ways to improve it? Thanks for sharing. 

Just some FYI: I’m seeing the same issues with disappearing android map markers. It definitely is related to two calls - setMapRegion (changing the map view area, which causes google maps to load new map textures - which introduces a delay in drawing the new map), and in the removeAllMarkers call.

If you make an addMarker call too soon after either of those calls on android, you run a good chance of no marker appearing on the display. You may also run into issues (when the timing is close, but not quite good enough), where markers do appear, but are malformed in some way, such as zoomed up (and clipped, so you see a large 1/4 of a marker), or even “ghost” looking (as if the alpha is at 0.05 or something). I’m guessing that when they aren’t there at all, it’s probably a variation of one of these two visual edge cases – ie; when it’s missing, it’s totally at the wrong scale and only transparent pixels are showing from the markers top left corner, or it’s alpha is messed up.

In any case, I’m seeing this bug pretty consistently on the galaxy S3 running 4.3. If the time between the removeAll (or a big view change using setMapRegion), and addMarker is less than 500ms, after a few cycles changing maps/removing markers, it’s messed up - no markers/malformed markers. Delays of 750ms or more, it works better / more consistently.  (This may be related to google maps code having to contact the google server to get new map info, but the corona code moves ahead adding markers before google changes the map properties??)

This in on WiFi. The delay has to be even longer over the cell net :frowning: