Mapview on Android

There’s not much we can do about the wait part, except tell the user we’re waiting for the device.

The iPhones I’ve tested on seem to have superior hardware to the androids… They seem to be able to get GPS coords right quick, no matter how deep I’m inside a building.

My current Android phone… I have to move near a window before it gets it…

Not sure why – I know there’s a few ways the iPhone can try to get the GPS coords— either through the actual GPS hardware, or through the cell network, or even through your wifi (iPods don’t have GPS hardware, and do it through a complex wifi process).

My guess is that android only uses the GPS hardware, which needs to be able to receive a signal from 3(?) satellites to determine it’s position… I don’t believe there’s a technical solution to this currently.

EDIT: To get regular GPS updates, as the hardware gets more accurate, and the user moves around, set the event handler for location to have your app updated periodically:

Runtime:addEventListener( “location”, locationHandler ) [import]uid: 79933 topic_id: 31115 reply_id: 124604[/import]

I have the location event listener setup and it is getting updates. My accuracy is in the 2000’s for awhile and eventually, in 10 seconds or so, it will get down to under 50.

What I don’t understand is how to code this so my app waits until the accuracy is under say 101 before it moves on. I have tried variations of the following with no luck.

[code]
– setup map
myMap = native.newMapView( 20, 20, 300, 220 )
myMap.mapType = “standard”
myMap.x = display.contentWidth / 2
myMap.y = 120
currentLocation = myMap:getUserLocation()

– function to get user’s current location
local locationHandler = function( event )
while event.accuracy > 100 or event.latitude == nil do
– my intent with the next line is to keep forcing updates but I’m not
– sure it is really doing as I intended
currentLocation = myMap:getUserLocation()
end
currentLatitude = currentLocation.latitude
currentLongitude = currentLocation.longitude

– Move map so that current location is at the center
myMap:setCenter( currentLatitude, currentLongitude )
end

Runtime:addEventListener(“location”, locationHandler)
[/code] [import]uid: 85963 topic_id: 31115 reply_id: 124616[/import]

I’d suggest you remove the while loop from your location handler… There’s a couple reasons why, but I digress…

Instead, the quick and dirty way would be to put your location handler in a separate lua file, and make a couple global variables (initialized to nil) in there (such as gps.long, gps.lat, gps.acc - or just save a copy of the last event struct if you want it all) …

Your main code can just keep checking them until not nil / accuracy is less than 100 or whatever your threshold is.

While it’s checking them and waiting, it could show a nice display of the current accuracy or something…

EDIT: You can use the runtime enterFrame event in your main app to regularly check on the gps accuracy, show messages, and/or call functions once the threshold has been triggered. [import]uid: 79933 topic_id: 31115 reply_id: 124622[/import]

Calling [lua]myMap:getUserLocation()[/lua] right after you created your map is *never* going to work on Android. You have to wait for the Android device’s GPS to startup and then get a fix on your location. And how long it will take will vary between different Android devices since they use different GPS sensors. This is just how it is and you need to write your code handle the case where the current location is unknown… because that same issue *can* happen on an iOS too, such as when the user puts the device into Airplane mode.

So, if you want to set up your code to fetch the user’s current location only once, then set up your timer to occur at regular intervals (not just a 1 shot timer) that continually calls the [lua]myMap:getUserLocation()[/lua] function. Once it receives the user’s current location, disable the timer.

Also, I highly recommend that you add the following 2 permission to your “build.settings” file…
[lua]settings =
{
androidPermissions =
{
“android.permission.ACCESS_FINE_LOCATION”,
“android.permission.ACCESS_COARSE_LOCATION”,
},
}[/lua]

The ACCESS_FINE_LOCATION gives your app permission to use the GPS. This provides the most precise current location measurements, but it takes time to get an initial fix on your current location. It also requires line-of-sight with the GPS satellites and generally does not work that well indoors, depending on how good the GPS sensor is.

However, the ACCESS_COARSE_LOCATION gives your app permission to retrieve your current location via WiFi and your cellular service. This is the fastest way to retrieve your current location, but it lacks precision.

Now, if you have both permission defined, then you’ll find that your app will first retrieve your current location via WiFi/cellular-service first and fairly quickly. Once the Android device gets a fix on the GPS satellites, it will provide GPS data instead. So, I highly recommend that you set both permission for the fast response time.

I hope this helps! [import]uid: 32256 topic_id: 31115 reply_id: 124623[/import]

One more thing. You should check out our updated map view documentation available on our daily build web page. That documentation has been heavily updated, provides more examples, and indicates what happens in the failure cases. It documents everything that I’ve mentioned above and should be a big help for you.

Please note that this documentation update is currently only available on our daily build page. The API documentation that you see on our website is only for our release build (#840) and we only update it per release. [import]uid: 32256 topic_id: 31115 reply_id: 124624[/import]

I tried out this code, cause I really want to start working on an app with MapView, but every thing I try results in the following error “This application encountered a lua error (see logs) or has been corrupted”. I just copy pasted everything, without changing anything, so I really don´t know how to fix it.

One time I got to the Corona SDK Trial frame saying “this message only appears in the trial version” and then all I got was a black screen :-(.
Ma Android version is 4.0.3 though, could that cause any problems ? [import]uid: 126207 topic_id: 31115 reply_id: 124991[/import]

janalbrechtjost.jost,

Map views are not available in the release version (build #894) of Corona for Android. This is a feature that we’ve added to Android recently and is only available to our paid subscribers. The release version that you are using only supports maps on iOS. Sorry about the confusion. [import]uid: 32256 topic_id: 31115 reply_id: 125146[/import]

@Joshua Quick
aah, allright, that explains it. Any idea if / when the MapView function will be available for test drivers ?

Thanks,

janalbrechtjost.jost [import]uid: 126207 topic_id: 31115 reply_id: 125151[/import]

It’s available to paying customers now via our daily build system.

Or you can wait for our next release of the Corona SDK. We have not decided on a release date yet, but we might release early so that everyone can test drive a version that fully supports iOS 6 and the iPhone 5. [import]uid: 32256 topic_id: 31115 reply_id: 125159[/import]

Ok, thanks a lot. Will it be possible to program for the Android device in the next release or will that stay limited to paying customers for a quite a while ? [import]uid: 126207 topic_id: 31115 reply_id: 125161[/import]

Yes, you can code for your Android device “today” will the current release version. The only reason it is crashing on you is because [lua]native.newMapView()[/lua] is returning nil and you are making calls on a nil object. Just get rid of that code and your app will work fine. In fact, if you look at the Android log via the Android SDK “adb logcat” or “ddms” tools, then it will clue you in where it is going wrong. [import]uid: 32256 topic_id: 31115 reply_id: 125172[/import]

Gentlemen, thank you both for your help but I am still struggling on this one. I have read over all of the available documentation and I am simply missing something.

It boils down to this: how do I “wait until” the GPS has a fix on the device location? Sounds simple but I have used timers, runtime event listeners, etc and no matter how I code it I can’t seem to get my program to “wait until” the GPS has a fix. Do either of you have a small working sample that shows how you wait on the GPS?

I promise I’m not a total dummy! I wrote the app listed below and all I had to do with IOS devices was call getUserLocation() twice and the device would get a location fix. Not the case with Android. Thanks! Scott

http://itunes.apple.com/us/app/nc-mobile-sex-offender-registry/id496296578?mt=8 [import]uid: 85963 topic_id: 31115 reply_id: 124899[/import]

If you’re not getting any GPS data, then are you testing your app indoors? Perhaps your Android device actually can’t get fix on your location. Try going outside and testing your app there. Remember that GPS requires line-of-sight to work… especially for the cheaper GPS sensors.

Also, did you add those 2 permission that I suggested up above? That 2nd permission will fetch your location from wifi and you’ll usually get location data within a few seconds.

One more thing, and this may sound like a stupid question, but are you sure location services are enabled on your Android device? Go to your device’s Settings screen, select “Location services” from the list, and make sure the below items are checked on:

  • Use wireless networks
  • Use GPS satellites

You might also want to run the Google maps app that came with your device to see if it can retrieve your current location too.
[import]uid: 32256 topic_id: 31115 reply_id: 124900[/import]

Joshua, no problems with the device or the signal. I am getting GPS data. All is setup correctly even the build.settings. I just cant seem to figure out how to write the code that will “wait until” I get a location fix before continuing on. For example, the “Location and Maps” sample that comes with the SDK initializes the map with preset hardcoded coordinates. How would I write the code to wait until I got the user’s current location and initialized it with that instead of the preset coordinates? It’s the “wait until” piece I am missing. Scott
[import]uid: 85963 topic_id: 31115 reply_id: 124902[/import]

No small working example – but I’ll write a little psuedo-code for you…

The main thing is – asynchronous. The GPS will respond when it wants. Your main program cannot just hard core loop and wait… So throw up a waiting screen if you have to, that show an accuracy figure (which will be modified as per the psudeo-code below).

local gpsLong = 0  
local gpsLat = 0  
local gpsAcc = 10000 -- some enormous value...  
  
function locationHandler(event)  
 gpsLong = event.longitude  
 gpsLat = event.latitude  
 gpsAcc = event.accuracy   
end  
  
function screenUpdate(event)  
  
 if( gpsAcc \< 101 ) then  
 print(" -- Accuracy acceptable, starting up") -- Let's get the party started...  
 else  
 print(" -- Accuracy still ", gpsAcc) -- Update user on how we are doing...  
 end  
end  
  
function main()  
  
 Runtime:addEventListener( "location", locationHandler )  
 Runtime:addEventListener( "enterFrame", screenUpdate )  
  
end  

No guarantees on the actual code above, it’s off the cuff. But the idea, events – are one way to do it, pretty easily. [import]uid: 79933 topic_id: 31115 reply_id: 124906[/import]

Bad post :frowning:

see below [import]uid: 79933 topic_id: 31115 reply_id: 124903[/import]

mpappas solution will work. (Thanks for that!)

The other way to do it based on your original code is like this…
[lua]-- Create the map view.
local myMap = native.newMapView( 20, 20, 300, 220 )

– Poll for current location and show it on the map.
local myTimerId = nil
local function callMap()
local currentLocation = myMap:getUserLocation()
if currentLocation.errorCode then
– Current location has not been received yet.
else
– Current location received. Show it on the map and disable the timer.
timer.cancel(myTimerId)
myMap:setCenter(currentLocation.latitude, currentLocation.longitude, true)
end
end
myTimerId = timer.performWithDelay(1000, callMap, -1)[/lua]

The above will poll the map view for the device’s current location via the map view. Once the current location has been discovered, it will display it in the map view and disable the timer. Now, if you want to continuously track the user’s current location, then remove the [lua]timer.cancel()[/lua] function. [import]uid: 32256 topic_id: 31115 reply_id: 124913[/import]

I tried out this code, cause I really want to start working on an app with MapView, but every thing I try results in the following error “This application encountered a lua error (see logs) or has been corrupted”. I just copy pasted everything, without changing anything, so I really don´t know how to fix it.

One time I got to the Corona SDK Trial frame saying “this message only appears in the trial version” and then all I got was a black screen :-(.
Ma Android version is 4.0.3 though, could that cause any problems ? [import]uid: 126207 topic_id: 31115 reply_id: 124991[/import]

janalbrechtjost.jost,

Map views are not available in the release version (build #894) of Corona for Android. This is a feature that we’ve added to Android recently and is only available to our paid subscribers. The release version that you are using only supports maps on iOS. Sorry about the confusion. [import]uid: 32256 topic_id: 31115 reply_id: 125146[/import]

@Joshua Quick
aah, allright, that explains it. Any idea if / when the MapView function will be available for test drivers ?

Thanks,

janalbrechtjost.jost [import]uid: 126207 topic_id: 31115 reply_id: 125151[/import]