gps not removed/disabled when app suspended via screen lock

Hello everybody.

I have a problem on my Android device (dont know if this happens on ios too).

I have build an app that uses the location of the user and it is working so far.

But when the app is suspended, the location listener is not removed correctly.

I tried to add Runtime:removeEventListener(“location”, locationHandler) on all system events that close or suspend the app in the onSystem listener, but it does not work always.

To reproduce the problem do the following:

Open the GPS sample project. (the map pin icon in the status bar appears)

Lock the screen.

Unlock the screen and close the App. (the map pin icon stays in the status bar)

Only when closing the app completely by swiping it off from the task manager removes the map pin from the status bar.

Is this the default/desired behaviour?

ps. closing the GPS sample app normally via the hard back button, or the home button without the forementioned procedure removes the map pin like expected.

Thank you in advance,

Felix

Hei everybody,

I am still facing this problem.

Anybody else has this problem or can reproduce it?

It is a big problem for me as my app that normally would use the location only at the start of the app keeps due to this bug?! searching for GPS until the battery is empty, what does not take much time in this case :confused:

Best,

Felix

On Android, when the app suspends, we turn off the GPS. We physically cannot access the GPS if we are not running in the foreground.

Rob

Hello Rob, thanks for your answer.

This is exactly the behaviour that I would expect, but it is not happening this way.

Please have a look at the GPS sample app.

When the app is in the foreground lock the screen.

Unlock it and the app should be back in the foreground. If you now press the home button or the back button (to quit the app) the gps stays activated no matter what you do (ex. removing the location event listener).

Only force quitting the app will switch off the GPS.

It seems to me, that during the lock process the gps gets corrupted or unloaded from the corona app and thus there is no chance to control it from within corona.

Best,

Felix

Can I get you file a bug report please?

Bug reports should contain a simple demo project that shows the bug. It should include a main.lua, config.lua, build.settings, and any assets needed to run and build the program. Use the “Report a bug” link at the top of the page. You will get an email with a CaseID number in the subject. Please post that number back here.

Rob

Ok,

Case 43973

Hope they will have an answer for this, or better, a solution :slight_smile:

Best,

Felix

Have you tried removing the location listener in your own suspend handler?

Rob

Hello Rob,

this is my onSystem listener:

local onSystem = function(event) if event.type == "applicationStart" then if showLogs then print("app started") end elseif event.type == "applicationExit" then Runtime:removeEventListener("location", locationHandler) if showLogs then print("app exited") end elseif event.type == "applicationSuspend" then Runtime:removeEventListener("location", locationHandler) if showLogs then print("app suspended") end elseif event.type == "applicationResume" then if showLogs then print("app resumed") end if acc \> minAcc or webViewState == "entregador" then --add the location service again Runtime:removeEventListener("location", locationHandler)--just to be sure that there is not already one... timer.performWithDelay( 500, function() Runtime:addEventListener("location", locationHandler) end) else Runtime:removeEventListener("location", locationHandler)--just in case... end end end

I read somewhere in the forums that double added eventlisteners can cause problems, so I remove it before adding it again.

Do you see something strange in this code?

Or should I remove the listener in another place as well?

Best,

Felix

The code looks pretty good. One thing I might do is add the location listener in the applicationStart that way you’re managing if it’s started or not.

Also make sure locationHandler exists before you do the addEventListener/removeEventListener and you’re not using it globally and trashing the value of locationHandler.

Rob

Hello Rob,

thank you once again for your answer.

I was adding the location eventListener at the end of my code, but on ppicatiion start feels way more professional :slight_smile:

I define the locationHandler variable before I create the function, like this:

local gpsButton = widget.newButton(...) --more gpsButton definitions and fillings --forward function declarations local locationHandler local someFunction local function something() --code end local function otherFunction() --code end --more functions and code function locationHandler(event) gpsButton.locationListener = true --code end --more functions and code -- Activate location listener (only on first start) if acc == nil or acc \> minAcc then if gpsButton.blinkHandle == false then gpsButton.fill = gpsSearching gpsButton.alpha = 1 gpsButton.blinkHandle = transition.blink(gpsButton, {time=1600}) end gpsButton.locationListener = false --to check if the listener was really called (ie. when the GPS is switched off) timer.performWithDelay( 1000, function() if not gpsButton.locationListener then Runtime:removeEventListener("location", locationHandler) showStatus("GPS desativado?", 2000) if gpsButton.blinkHandle then transition.cancel(gpsButton.blinkHandle) gpsButton.blinkHandle = false end gpsButton.fill = gpsDisCon gpsButton.alpha = 1 gpsTimerHandle = false end end) Runtime:addEventListener("location", locationHandler) end

This forward declaration should avoid that the locationHandler is redefined when it is first time called, or am I mistaken?

Here you can also see how I add the location eventListener. I created some additional mechanics to check if the locationHandler was called or not, because if the GPS is switched off, it is not called at all…

Maybe you can spot some problem in this piece of code?

Thank you,

Felix

I don’t see anything inherently wrong with your code.

Rob

Hei everybody,

I am still facing this problem.

Anybody else has this problem or can reproduce it?

It is a big problem for me as my app that normally would use the location only at the start of the app keeps due to this bug?! searching for GPS until the battery is empty, what does not take much time in this case :confused:

Best,

Felix

On Android, when the app suspends, we turn off the GPS. We physically cannot access the GPS if we are not running in the foreground.

Rob

Hello Rob, thanks for your answer.

This is exactly the behaviour that I would expect, but it is not happening this way.

Please have a look at the GPS sample app.

When the app is in the foreground lock the screen.

Unlock it and the app should be back in the foreground. If you now press the home button or the back button (to quit the app) the gps stays activated no matter what you do (ex. removing the location event listener).

Only force quitting the app will switch off the GPS.

It seems to me, that during the lock process the gps gets corrupted or unloaded from the corona app and thus there is no chance to control it from within corona.

Best,

Felix

Can I get you file a bug report please?

Bug reports should contain a simple demo project that shows the bug. It should include a main.lua, config.lua, build.settings, and any assets needed to run and build the program. Use the “Report a bug” link at the top of the page. You will get an email with a CaseID number in the subject. Please post that number back here.

Rob

Ok,

Case 43973

Hope they will have an answer for this, or better, a solution :slight_smile:

Best,

Felix

Have you tried removing the location listener in your own suspend handler?

Rob

Hello Rob,

this is my onSystem listener:

local onSystem = function(event) if event.type == "applicationStart" then if showLogs then print("app started") end elseif event.type == "applicationExit" then Runtime:removeEventListener("location", locationHandler) if showLogs then print("app exited") end elseif event.type == "applicationSuspend" then Runtime:removeEventListener("location", locationHandler) if showLogs then print("app suspended") end elseif event.type == "applicationResume" then if showLogs then print("app resumed") end if acc \> minAcc or webViewState == "entregador" then --add the location service again Runtime:removeEventListener("location", locationHandler)--just to be sure that there is not already one... timer.performWithDelay( 500, function() Runtime:addEventListener("location", locationHandler) end) else Runtime:removeEventListener("location", locationHandler)--just in case... end end end

I read somewhere in the forums that double added eventlisteners can cause problems, so I remove it before adding it again.

Do you see something strange in this code?

Or should I remove the listener in another place as well?

Best,

Felix

The code looks pretty good. One thing I might do is add the location listener in the applicationStart that way you’re managing if it’s started or not.

Also make sure locationHandler exists before you do the addEventListener/removeEventListener and you’re not using it globally and trashing the value of locationHandler.

Rob

Hello Rob,

thank you once again for your answer.

I was adding the location eventListener at the end of my code, but on ppicatiion start feels way more professional :slight_smile:

I define the locationHandler variable before I create the function, like this:

local gpsButton = widget.newButton(...) --more gpsButton definitions and fillings --forward function declarations local locationHandler local someFunction local function something() --code end local function otherFunction() --code end --more functions and code function locationHandler(event) gpsButton.locationListener = true --code end --more functions and code -- Activate location listener (only on first start) if acc == nil or acc \> minAcc then if gpsButton.blinkHandle == false then gpsButton.fill = gpsSearching gpsButton.alpha = 1 gpsButton.blinkHandle = transition.blink(gpsButton, {time=1600}) end gpsButton.locationListener = false --to check if the listener was really called (ie. when the GPS is switched off) timer.performWithDelay( 1000, function() if not gpsButton.locationListener then Runtime:removeEventListener("location", locationHandler) showStatus("GPS desativado?", 2000) if gpsButton.blinkHandle then transition.cancel(gpsButton.blinkHandle) gpsButton.blinkHandle = false end gpsButton.fill = gpsDisCon gpsButton.alpha = 1 gpsTimerHandle = false end end) Runtime:addEventListener("location", locationHandler) end

This forward declaration should avoid that the locationHandler is redefined when it is first time called, or am I mistaken?

Here you can also see how I add the location eventListener. I created some additional mechanics to check if the locationHandler was called or not, because if the GPS is switched off, it is not called at all…

Maybe you can spot some problem in this piece of code?

Thank you,

Felix