GPS-problems on new Huawei P20 and 30

My app has problems when used on Huawei P20 and P30. On other mobiles, the coordinates from the GPS comes regularily once per second. On the P20 and P30 only one coordinate pair comes when the app is started. And this coordinate pair has a very low accuracy (more than 2000m).

I have discovered that when I open e.g Google maps, it initially shows my position to be wrong, but after 1-2 seconds it jumps to the correct position. My app doesn’t. It’s stuck with the initial erroneous position.

So to the question. Is there a way to request new positions from the GPS from Corona? Or is there some other solution to this problem. I have tried all kinds of battery save settings on/off, position using wifi on/off, GPS on/off, but none seem to cure the problem.

Any help on this will be highly appreciated!

Corona uses the Location Services provided by the operating system. In general it works like this:

  1. Get your current location from connected WiFi or triangulated by various Cell towers. The accuracy of this isn’t very good. It’s why you start with a large circle.

  2. Next, location services attempts to connect to the GPS constellation (cluster) of satellites. Your phone has to see at least four visible satellites and get signal from them to get more accurate data. It doesn’t take a lot of metal in a building to block receiving and causing the visible satellites to drop below enough needed. You certainly should step outdoors and give it a minute to acquire signal. The US has 32 satellites in its constellation.  Other countries could have fewer making acquisition more difficult.

  3. You can put a print statement in your event handler for location services and print out the values in the event table. If you don’t see the time changing, you probably have not acquired GPS, but you should see events generating reasonably frequently (once a second or so). If your signal is coming from cell tower triangulation or from the local WiFi you’re on, your location isn’t going to change.

  4. You have to have all your location services permissions correctly. Starting with Android 6, you have to request a dialog box to get the user’s permission to access location services. There are two permissions:
     

“android.permission.ACCESS_FINE_LOCATION”,

“android.permission.ACCESS_COARSE_LOCATION”,

The second one will get you the Cell tower/WiFi location, but you have to have FINE_LOCATION to get GPS data. If you’re not requesting these permissions correctly, Corona may not be allowed to receive GPS information. The best example would be to look in the Corona Sample App: “Camera”, it’s in the “SampleCode/Media/Camera” folder and make sure you’re requesting and have been granted the FINE_LOCATION permission.

This may be why Google Maps works and your app doesn’t.

Rob

Hi Rob,

Thanks for your quick reply. The permissions for my app are

    androidPermissions =

    {

        “android.permission.INTERNET”,

        “android.permission.ACCESS_FINE_LOCATION”,

        “android.permission.ACCESS_COARSE_LOCATION”,

    },

…so they should be OK. My app has been in extensive use for 4-5 years by 3.000 users, and have worked flawlessly until Huawei launched their P20 and P30 models.

What puzzles me is that Google maps obtains the correct position after 1-2 seconds, my app doesn’t. And this is only a Huawei P20/30 issue.

without seeing your code it’s hard to suggest anything, but did yo try:

https://docs.coronalabs.com/api/type/Map/getUserLocation.html

what method do you use to update gps position?

i use a similar approach like this:

https://forums.coronalabs.com/topic/36981-gps-location-update-frequency/

making  a timer before creating the map and after trying to get a gps position, help me a lot also to show the correct position at first.

Thanks for your tips, carloscosta! I have been playing around with my code today, and found exactly the same solution as mentioned on the forum, retrigger the GPS by executing

  Runtime:removeEventListener( “location”, locationHandler )

  Runtime:addEventListener( “location”, locationHandler )

So if no coordinates come from the GPS within a timeout (2 seconds) I just kickstart it again by stopping av starting.

I have observed the Position icon on the display top disappears and reappears during this kickstart. Don’t know if this has an impact on the overall accuracy, I suspect the GPS isn’t too happy with being kicked around :wink:

I keep on trying and will revert to the forum if I find a good solultion.

i used this functions:

function gps.oneTimeCoordinates(funcIn) local func=funcIn or nil local object = {} object.location = function(object, event) if event.errorCode then native.showAlert( "GPS Location Error", event.errorMessage, {"OK"} ) print( "Location error: " .. tostring( event.errorMessage ) ) else Runtime:removeEventListener( "location", object) end if func then func(event) end end if system.hasEventSource( "location" ) then Runtime:addEventListener("location", object) end end function gps.new(paramsIn) local mainGroup={} local params=paramsIn or {} local func=params.func or nil local threshold=params.threshold or 5 local accuracy=params.accuracy or 10 local locationHandler = function( event ) if ( event.errorCode ) then native.showAlert( "GPS Location Error", event.errorMessage, {"OK"} ) print( "Location error: " .. tostring( event.errorMessage ) ) else if func then func(event) -- sending latitude and longitude to use outside this function end end end if system.hasEventSource( "location" ) then system.setLocationThreshold( threshold ) system.setLocationAccuracy( accuracy ) Runtime:addEventListener( "location", locationHandler ) end mainGroup.locationHandler=locationHandler return mainGroup end function gps.updateCoordenates(objIn) local obj=objIn if obj then local locationHandler=obj.locationHandler if locationHandler then Runtime:removeEventListener( "location", locationHandler ) Runtime:addEventListener( "location", locationHandler ) end end end

in the main program i’ve something like this:

local lat=0 local lng=0 local function openGPS(event) lat=event.latitude or 0 lng=event.longitude or 0 end local gpsLocation=gps.new({func=openGPS}) local locationHandler=gpsLocation.locationHandler

Corona uses the Location Services provided by the operating system. In general it works like this:

  1. Get your current location from connected WiFi or triangulated by various Cell towers. The accuracy of this isn’t very good. It’s why you start with a large circle.

  2. Next, location services attempts to connect to the GPS constellation (cluster) of satellites. Your phone has to see at least four visible satellites and get signal from them to get more accurate data. It doesn’t take a lot of metal in a building to block receiving and causing the visible satellites to drop below enough needed. You certainly should step outdoors and give it a minute to acquire signal. The US has 32 satellites in its constellation.  Other countries could have fewer making acquisition more difficult.

  3. You can put a print statement in your event handler for location services and print out the values in the event table. If you don’t see the time changing, you probably have not acquired GPS, but you should see events generating reasonably frequently (once a second or so). If your signal is coming from cell tower triangulation or from the local WiFi you’re on, your location isn’t going to change.

  4. You have to have all your location services permissions correctly. Starting with Android 6, you have to request a dialog box to get the user’s permission to access location services. There are two permissions:
     

“android.permission.ACCESS_FINE_LOCATION”,

“android.permission.ACCESS_COARSE_LOCATION”,

The second one will get you the Cell tower/WiFi location, but you have to have FINE_LOCATION to get GPS data. If you’re not requesting these permissions correctly, Corona may not be allowed to receive GPS information. The best example would be to look in the Corona Sample App: “Camera”, it’s in the “SampleCode/Media/Camera” folder and make sure you’re requesting and have been granted the FINE_LOCATION permission.

This may be why Google Maps works and your app doesn’t.

Rob

Hi Rob,

Thanks for your quick reply. The permissions for my app are

    androidPermissions =

    {

        “android.permission.INTERNET”,

        “android.permission.ACCESS_FINE_LOCATION”,

        “android.permission.ACCESS_COARSE_LOCATION”,

    },

…so they should be OK. My app has been in extensive use for 4-5 years by 3.000 users, and have worked flawlessly until Huawei launched their P20 and P30 models.

What puzzles me is that Google maps obtains the correct position after 1-2 seconds, my app doesn’t. And this is only a Huawei P20/30 issue.

without seeing your code it’s hard to suggest anything, but did yo try:

https://docs.coronalabs.com/api/type/Map/getUserLocation.html

what method do you use to update gps position?

i use a similar approach like this:

https://forums.coronalabs.com/topic/36981-gps-location-update-frequency/

making  a timer before creating the map and after trying to get a gps position, help me a lot also to show the correct position at first.

Thanks for your tips, carloscosta! I have been playing around with my code today, and found exactly the same solution as mentioned on the forum, retrigger the GPS by executing

  Runtime:removeEventListener( “location”, locationHandler )

  Runtime:addEventListener( “location”, locationHandler )

So if no coordinates come from the GPS within a timeout (2 seconds) I just kickstart it again by stopping av starting.

I have observed the Position icon on the display top disappears and reappears during this kickstart. Don’t know if this has an impact on the overall accuracy, I suspect the GPS isn’t too happy with being kicked around :wink:

I keep on trying and will revert to the forum if I find a good solultion.

i used this functions:

function gps.oneTimeCoordinates(funcIn) local func=funcIn or nil local object = {} object.location = function(object, event) if event.errorCode then native.showAlert( "GPS Location Error", event.errorMessage, {"OK"} ) print( "Location error: " .. tostring( event.errorMessage ) ) else Runtime:removeEventListener( "location", object) end if func then func(event) end end if system.hasEventSource( "location" ) then Runtime:addEventListener("location", object) end end function gps.new(paramsIn) local mainGroup={} local params=paramsIn or {} local func=params.func or nil local threshold=params.threshold or 5 local accuracy=params.accuracy or 10 local locationHandler = function( event ) if ( event.errorCode ) then native.showAlert( "GPS Location Error", event.errorMessage, {"OK"} ) print( "Location error: " .. tostring( event.errorMessage ) ) else if func then func(event) -- sending latitude and longitude to use outside this function end end end if system.hasEventSource( "location" ) then system.setLocationThreshold( threshold ) system.setLocationAccuracy( accuracy ) Runtime:addEventListener( "location", locationHandler ) end mainGroup.locationHandler=locationHandler return mainGroup end function gps.updateCoordenates(objIn) local obj=objIn if obj then local locationHandler=obj.locationHandler if locationHandler then Runtime:removeEventListener( "location", locationHandler ) Runtime:addEventListener( "location", locationHandler ) end end end

in the main program i’ve something like this:

local lat=0 local lng=0 local function openGPS(event) lat=event.latitude or 0 lng=event.longitude or 0 end local gpsLocation=gps.new({func=openGPS}) local locationHandler=gpsLocation.locationHandler