Monitoring location updates on Android in a consistent fashion (e.g in a service, and while the screen is locked) can be quite a challenge. This article tackles the problem head-on
UPDATE: This article, and the demo for it, has been superceded by this article and the demo associated with it. Please refer to that, instead of this article.
The code discussed in this article was designed using Delphi 10.2 Tokyo Release 2, however it should at least work on Berlin, and possibly Seattle. For those who want to make a fast start, go to the Kastri Free project and download it. The demo project for this article is in the Demos\AndroidLocation folder.
Developing an app with location updates is, on the face of it, fairly straightforward. You create a new Firemonkey app, put a TLocationSensor on the form, and away you go. However, if your intention is to track the device while the app is not even running, you need to use a service. Even if you’re tracking just using an app, when the screen is locked, the situation can change. This discussion focuses on the former problem, i.e. tracking the device when the app is not even running.
These are the main points that I’ll cover:
- Starting the service when the device is turned on, or “restarted”
- Monitoring the device for when the screen is locked/unlocked, and when entering/exiting “doze” mode
- Moving the service into the “foreground”, so that it still has network access even when the screen is locked
- Catering for “doze” mode
- Other techniques used in the demo
- Communicating with a server
Starting the service on boot or restart
If you have a service that tracks the device location, you might want it to start when the device is turned on, or when it is restarted (which can be two different things now), so that tracking starts immediately. You may have in the past seen articles that cover being able to start an application at boot, however what if the user does not necessarily want to see the app start when the device starts?
The answer is in some Java code I have devised that acts as a “multipurpose” broadcast receiver. The code is part of the Kastri Free project, in DWMultibroadcastReceiver.java. This code will respond when the device boots, and take action depending on which intent actions are being filtered, including starting the service, and monitoring alarms.
In order to be able to start the service at boot or restart, and to monitor for the “doze” alarm, there are a couple of entries made in the manifest, as per this image:
Monitoring for screen lock and “doze” mode
When the screen is locked, after a period of time on later versions of Android, the system restricts network access to processes that are running in the foreground. To make matters worse, on later versions of Android, if the device is locked for an extended amount of time (somewhere around an hour on my Nexus 5X running Android 8.1) it can enter what is called “doze” mode, where it may not receive location updates.
To monitor for when the screen is locked or unlocked, or enters or exits “doze” mode, the service needs to register a receiver to listen for broadcasts for those specific intent actions. In the demo code, this is handled by the TServiceReceiver class, which forwards the intent on to the service.
“Moving” the service into the foreground
To alleviate the network access problem when the screen is locked, the service needs to be “moved” into the foreground. When the service detects the screen is locked, it calls StartForeground, which puts it into the foreground state. Foreground services require that a notification is supplied, which means that a notification icon would normally appear (if the screen was unlocked) in the status bar. When the screen is unlocked, the service calls StopForeground, which puts it out of foreground state. Since the service is in the foreground only when the screen is locked, the user will notice the notification only when the lock screen is viewed:
Catering for “doze” mode
When in this state, the only way to keep posting regular updates (although the device will be stationary anyway) is by use of an alarm, set with the AlarmManager, and in a special “allow when idle” mode. When using an alarm in this mode, the documentation says that it should be set at no more than once per 9 minutes.
As above, the service monitors for changes in lock mode, and when entering lock mode, sets an alarm. When the alarm goes off, the multipurpose receiver (described in the first section) “starts” the service (although in this case it has already started), and in the AndroidServiceStartCommand event updates the location using getLastKnownLocation, and resets the alarm.
Other techniques used in the demo
If you study the code, you may notice that it does not use TLocationSensor. Part of the reason for this is that it needs an instance of the Android LocationManager anyway (JLocationManager in Delphi) in order to call getLastKnownLocation, and I wanted to make sure that I had absolute control over how the listeners were set up etc. It’s quite possible that the same result could be achieved by using TLocationSensor.
Also, you may notice the use of a timer (not an FMX TTimer, though), which is set to a 4 minute interval. This is a “hangover” from experimentation of location updates when the screen is locked, and when the device enters doze mode. I have left it in, in case it might be needed in the future.
Communicating with a server
The whole point of the demo is so that when a location update is available, it can be sent to a server of some kind. In this case, it’s geared towards sending a JSON request to (presumably) a REST server. If you use this part of the demo, you could modify the cLocationUpdateURL to one of your own, and modify cLocationRequestJSON to suit your own requirements.
If you’re just interested in experimenting with the demo and don’t have your own server, you may contact me, and I can set you up to access mine.
As always, instead of explaining a lot of the code, I will field questions if you have any.
I’d like to thank Atek Sudianto, from Jakarta, Indonesia who set me down this path. I am in the planning stages of an app that requires all of what I’ve covered in this article, and his enquiries gave me the “prod” I needed.
Thanks. This was a great read. Greetings from Brazil.
Very good thank you! I have a doubt I have a project that used TMaps but I added the PUSH of Firebase according to this article (http://blog.delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps- part-1 /) so that TMaps no longer responds because of Lib. I wonder if I can add this service to my application and TMaps would work again? Thanks again
What do you mean by “no longer responds”? The libraries required by TMapView are included in the play-services-base.jar, which is added to the project, so it should still work.
Thank you very much for this article and for sharing the demo. It’s really great work and it’s very helpful due to lack of information regarding this topic.
I’m really thankful for the post. I’d like to know how to install the component to use AndroidLocation.
There is no component related to this article to install. Are you having a specific problem with the code?
Thank you very much for your attention.
Sorry for the writing here because I’m a Brazilian using google translate.
I was able to generate the DEMO AndroidLocation today, but the APP closes after a few seconds of started, can you help with some information?
I am currently using the Delphi version 10.1 berlin upd 2.
O problema é possivelmente por causa da versão do Android. Eu atualizei este arquivo:
https://github.com/DelphiWorlds/KastriFree/blob/master/Demos/AndroidLocation/Service/LS.ServiceModule.pas
Esta alteração possivelmente resolverá seu problema
problem with android 8.0 (api 26): https://developer.android.com/about/versions/oreo/background-location-limits 🙁
I developed the demo for this article on an Android 8 (API 26) device, taking into account the background limits (which is why the AlarmManager is used). Is there a specific problem you are having?
Thanks for great example. I tried to use your code without the location listeners, becase all I need is to check updates on my server on the timer event. And the timer stops working after reboot of the phone (and after shut down -> start). It looks like Android doesn’t pause the application just because it uses GPS.
The timer *should* work after a reboot, so I don’t know why it would not. I need to update the demo anyway, so I will check that soon
I was wrong about restart – it does not matter. It pauses when I remove the USB cable (so it works on the battery), and the phone goes to the sleep mode. In this case during the sleep mode the timer event does not work. After I unlock the phone, it continues working without problems. As I said, this problem occurs only if I remove the GPS-related code from your source. But I think, for your readers, it may be interesting to have an always-working service, not dependent on GPS and external power supply. By the way, the OS version is 5.0.2. Thanks!
I’ve now updated the source for the demo. The Pause/Resume functions now turn the location services on/off completely, and I’ve added support for API 26+
Thanks for update! But something strange happens with the Pause/Resume button. It updates the caption first time when I click on it (switches to “Resume Updates”), but the GPS still work. And after that it “does not react” to my clicks (the caption is always “Resume Updates”), although it’s enabled.
I think I may know what the problem is. I’m working on another update to solve the issue.. stay tuned.
I think I have everything working as it should now. Please make sure you have all changed and new files in the demo project, ensure you have the updated dw-multireceiver.jar in the Lib folder, and ensure you do a Clean/Build. If you have further issues, please report it to here: https://github.com/DelphiWorlds/KastriFree/issues
Thanks, the “Pause/Resume Updates” works without problems now. But this has nothing to do with the initial problem I described: when you pause location updates and switch your phone into sleep mode, the timer stops working (that is, Android pauses the service). Nothing has changed here 🙁
Is this for when the device is rebooted? If so, I’ve just checked in fixes (including dw-multireceiver.jar) so that the service actually starts properly on boot for API 26+ (for lower targets it should still work)
For the general case, I tested the timer by making the interval 30 seconds (cLocationMonitoringInterval value of 30000) and watching the messages in Monitor – it works fine for me.
>Is this for when the device is rebooted?
No. 1) Disconnect the phone from the power source (let it work on the battery). 2) Turn off location updates (click on your button) and close the application. 3) Put the phone into sleep mode. 4) Wait for 2-3 minutes. 5) Unlock the phone. 6) Run application and watch the log: can you see the TimerHandler for the past 2-3-minutes? I can’t.
Fixed in the latest update, through the use of a wake lock. Make sure you update the changed files, including dw-multireceiver.jar
Very strange… I’ve updated all KastriFree folder, but the Timer still doesn’t work in sleep mode when updates are disabled. I can see your changes – the application is not showing on the lock screen anymore that is great. The WakeLock is set in User Permissions. But the problem with the timer remains…
It looks like an impossible task for the today’s Delphi platform – to get periodical updates from the server 🙁
I’ve added my messages to code to see what happens. The EnableWakeLock(true) wasn’t running because CheckBuildAndTarget(26) returns FALSE. Alhough I’m using the Android SDK 26.0.2:
https://snag.gy/r86hJ1.jpg
how to turn of mock location or developer option?
Turn off, or turn on?
If you mean “on”, on Android, use something like Fake GPS. It’s not possible on a real iOS device, however you can do it in Simulator using the Debug|Location option from the Simulator menu. For a real iOS device, you’d need to do it in code (i.e. simulate location updates yourself, not even using TLocationSensor)
Hi, Thank you for all of your hard work. Ive been trying to compile your demo, and I am getting lots of path errors.. Im a little lost.. All Im trying to do is create an app for our delivery trucks.. It will be a foreground service, and will Always be running tracking the location of the driver. Every 3-5 minutes, it will send the long lat to my server. Have no trouble doing this in a normal app. I will use a mobile device manager to lock the phone down, so the driver can not remove the app. Is there some really straight forward demo app that I can start with, using simply Location and will run at startup? Im really lost with all of the options.
Please be aware that the demo relies on the Kastri Free library, so just downloading the project and files from the demo is not going to work. If you have downloaded the entire library, the demo project should compile from where it is located.
The whole premise of the article is to ensure that location updates happen whether or not the application is running, or is in the background. If you know your app will never go into the background (which will happen if the screen becomes locked), and not be shut down, you may be able to get away with just using TLocationSensor as per the demo supplied with Delphi.
Having said that, for apps that need location monitoring continuously (i.e. on startup, and whether or not the app is running or in the background), the demo is about as straightforward as it can be. If you do have the Kastri Free library and are compiling the demo from within it, please let me know what errors you are seeing.
Thank you for the reply. I messed with it at length today.. I have all of the lib paths right in delphi, Bin, core dirs etc.. Your paths are fine. The problem I have is trying to figure out why when I try to compile your code (Vs other android code) it gives me this weird path error, saying it is trying to look for the file javac.exe .. in weird dirs. I cant find where those weird paths are stored and then appended to my Environment path..
Build started 11/21/2018 8:57:57 PM.
__________________________________________________
Project “C:\_Delphi Tools\KastriFree-master\Demos\AndroidLocation\Service\LocationService.dproj” (Make target(s)):
Target BuildVersionResource:
c:\program files (x86)\embarcadero\studio\19.0\bin\cgrc.exe -c65001 “LocationService.vrc” -foLocationService.res
CodeGear Resource Compiler/Binder
Version 1.2.2 Copyright (c) 2008-2012 Embarcadero Technologies Inc.
Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
Copyright (C) Microsoft Corporation. All rights reserved.
Deleting file “LocationService.vrc”.
Target BuildAndroidServiceJarFile:
“\bin\javac” -d “C:\_Delphi Tools\KastriFree-master\Demos\AndroidLocation\Service\JavaClasses\LocationService” -Xlint:deprecation -classpath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar”;”c:\program files (x86)\embarcadero\studio\19.0\lib\Android\Debug\fmx.jar” -bootclasspath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar” -encoding UTF-8 -target 1.6 -g -source 1.6 .\Android\Debug\LocationService.java .\Android\Debug\LocationServiceProxyInterface.java
The system cannot find the path specified.
c:\program files (x86)\embarcadero\studio\19.0\bin\CodeGear.Common.Targets(811,5): error MSB3073: The command “”\bin\javac” -d “C:\_Delphi Tools\KastriFree-master\Demos\AndroidLocation\Service\JavaClasses\LocationService” -Xlint:deprecation -classpath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar”;”c:\program files (x86)\embarcadero\studio\19.0\lib\Android\Debug\fmx.jar” -bootclasspath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar” -encoding UTF-8 -target 1.6 -g -source 1.6 .\Android\Debug\LocationService.java .\Android\Debug\LocationServiceProxyInterface.java” exited with code 3.
Done building target “BuildAndroidServiceJarFile” in project “LocationService.dproj” — FAILED.
Done building project “LocationService.dproj” — FAILED.
Build FAILED.
c:\program files (x86)\embarcadero\studio\19.0\bin\CodeGear.Common.Targets(811,5): error MSB3073: The command “”\bin\javac” -d “C:\_Delphi Tools\KastriFree-master\Demos\AndroidLocation\Service\JavaClasses\LocationService” -Xlint:deprecation -classpath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar”;”c:\program files (x86)\embarcadero\studio\19.0\lib\Android\Debug\fmx.jar” -bootclasspath “C:\Users\Public\Documents\Embarcadero\Studio\19.0\CatalogRepository\AndroidSDK-2433_19.0.31059.3231\platforms\android-22\android.jar” -encoding UTF-8 -target 1.6 -g -source 1.6 .\Android\Debug\LocationService.java .\Android\Debug\LocationServiceProxyInterface.java” exited with code 3.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.17
Hi Dave,
i try to implement this project merge with FCMRevisited app,
i have question about identity of sender location, i find deviceid parameter in cLocationRequestJSON.
but in code ony find LStream := TStringStream.Create(Format(cLocationRequestJSON, [‘x’, NewLocation.Latitude, NewLocation.Longitude, LTag, Ord(FIsDozed)]));
where i can get this ‘X’ value
The JSON being sent is just an example – you could send something entirely different, however here it’s a substitute for an id representing the device for your application. You could use a number of ways for the real value, including (instead of the ‘x’ literal) using TOSDevice.GetUniqueDeviceID (from the DW.OSDevice unit).
Ok , ‘X’ replaace by TOSDevice.GetUniqueDeviceID and in front app when signup i have to include TOSDevice.GetUniqueDeviceID as one field in server, correct?
Thanks dave,
Hy!
Thank you for the demo app. When I try to compile the whole project, it says DW.FileWriter not found. Is there anything like DW unit or something?
Thanks!
DW.FileWriter is part of the KastriFree library, which the demo relies on. If you have downloaded the whole KastriFree library, for the LocationService app in the Project Options, under Building > Delphi Compiler, for a Target of All Configurations – All Platforms, please change the value for Search Path to:
..\Common;..\..\..\API;..\..\..\Core
That should fix the problem.
Thanks!
And if I try to integrate the location service into another application, how am I supposed to do it? I mean Ive already added the service to that app, but It crashes all the time on a specific phone, but if I use the original Demo app ( from your git ), It works properly. Did u just add the service to your project, on the proper way? ( android target->add service )
When compiler said there are missing files, I just dropped files into the IDE from my desktop 😀 Can it be a problem?
> It crashes all the time on a specific phone
You’ll need to provide more information about the crashes for me to work out what the problem is, although you should ensure that dw-multireceiver.jar is added to the application project, i.e. in Project Manager, under Target Platforms > Android > Libraries, right-click the “Libraries” node, click “Add”, then select the dw-multireceiver.jar file.
> When compiler said there are missing files..
Which files are those?
I solved the missing files problem, thanks, but Can it be a problem that I always start the android Service at opening my app? I read your code, and found that line where you start the service, but only in that case, if it isn’t running. I added the multireceiver file, and it’s still the same, randomly crashing 🙁 Is there anything I need to handle at starting service? So I mean If I add ther service ( add service on android target ), and I start it every time when I open my app, should it work? Or is there anything special to do ( like start service only when its not running )? So is it enough if i just add service to my app, and link all the missing files?
I strongly suggest you learn how to use a logcat viewer, such as Monitor, as described at “10. Build, run and test the project” in this article: http://delphiworlds.com/2017/05/add-firebase-cloud-messaging-mobile-apps-part-1/. That may help in determining why your app is crashing. Other than that, I’d need to see the code.
Hi Dave, first of all great info and great demo’s! I’ve been working with the LocationDemo on Delphi Rio for some time now and most of the things seem te work nice. However the location isn’t determined when the screen is off. I’m guessing it has something to do with the startforeground part of the servcie (command is logged but, i dont see a notification in the lock screen). Any ideas there?
Hi Martijn,
If the notification is not showing then yes, presumably StartForeground is not being called. This is called if you make the app inactive, *and* SendCommand(cServiceCommandAppEnteredBackground) is called from the app (as per the demo), or if the device is put into the lock screen. If you know how to use a logcat viewer (such as Monitor), you could use it to see what messages are being logged by the code. That should give you an idea of what is going on.
Hi Dave, thanks! By using mLogCat i was able to find out why things didnt work. With the startforeground command the logs showed there was no channel found for the notification. Once i added it, things seemed to start working!
Of course! I’ll have to update the demo to fix that; thanks!
Hi Dave! Thanks for this great demo. Any update for this notification? JNotificationChannel is missing from my side. I think there is a conflict between Androidapi.JNI.App and DW.Androidapi.JNI.App.
Hi Gerry,
Can you let me know exactly what the issue is, and provide an example? The demo as-is compiles OK. Thanks!
Hi Dave!
Thanks for the reply. By the way I’m using Tokyo(10.2.2) but unfortunately i was not able to compile the demo project. Error as shows [DCC Error] LS.ServiceModule.pas(82): E2003 Undeclared identifier: ‘JNotificationChannel’.
Note: When I compile in Rio(10.3.1) I was able to build and run but it will show black screen in android 7.0 device.
Regards,
Gerry
Could you try running DeviceLens, which is here: https://github.com/DelphiWorlds/MiscStuff/blob/master/Test/DeviceLens.zip
Enter the package id (e.g. com.embarcadero.TestApp) for your app in the “Filter On Package Name” edit and hit enter, then start your app?
The messages may give a clue as to what the issue is
Hi Dave, upon further working with the example we experience an inconveniant problem on Android 9 devices. The demo shows a message “Detected problems with API compatibility”. When looking into this I found it is being caused by the app using “dark greylist” functions.
LogCat gave me:
ds.locationdem: Accessing hidden method Landroid/view/MotionEvent;->()V (dark greylist, JNI): com.delphiworlds.locationdemo
(Also there are some light greylist functions, but i dont think they are an issue.)
Any ideas on how to solve this?
Further more we also experience the app isnt responding in some cases when screen has been disabled and it has to come back from foregroundmode. Andoird shows “LocationApp isn’t responding”. I havent been able to determine the cause and sadly logcat didnt provide a clue. Any thoughts here ?
Thanks anyway 🙂
Hi Martijn,
The problem on Android 9 is a general issue with Delphi apps on Android 9. Hopefully it will be fixed in the next version of Delphi.
Regarding your other issue: I have been experiencing that myself. I plan to do a substantial revamp of the demo in the next couple of weeks, to resolve that issue, and others.
First of all congratulations for the great work in the kastri library, I have a problem implementing the example in android 9 (I think the problem is when calling StartForeground (), it works perfect in android 6 and 8, there is something new in the development of the example? I use delphi 10.3.3. greetings from Argentina!
Hi Javier,
I have been working on a revised version of the location monitoring for Android, which I plan to publish an article for very soon. It’s being tested on Android 9 and 10, and includes support for iOS
Hi Javier, In case you’ve missed it, the new article is here: http://delphiworlds.com/2020/01/cross-platform-location-monitoring/
hi Dave, yes, it works great on android 8 and 9! In android 6 I did not get it to work but anyway a service is not necessary in this case thank you very much!
Hi,
just come across KastriFree and seen this post. I need to replicate the functionality in a project. eg keep posting to a MYSQL database in the background.
I can’t see any documentation on using the library ( new to delphi ).
Do I simply copy over the files needed ??
Cheers
After some searching I added the following to the library path.
C:\Program Files (x86)\Embarcadero\Studio\20.0\lib
C:\Program Files (x86)\Embarcadero\Studio\20.0\core
C:\Program Files (x86)\Embarcadero\Studio\20.0\SDK
Am I missing anything else ?
I tested the AndroidBackgroundDemo and it worked ok.
Feeling pleased with myself I opened the LocationApp.
When I tried compile I got :
[Exec Error] The command “PATH C:\Program Files\Java\jdk1.8.0_60\bin;C:\Users\Public\Documents\Embarcadero\InterBase\redist\InterBase2020\IDE_spoof;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Embarcadero\Studio\20.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\20.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\150\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\150\DTS\Binn\;C:\Program Files\dotnet\;C:\Program Files (x86)\Embarcadero\Studio\20.0\LabPacks\OpenWire Studio\Win32\;C:\Program Files (x86)\Embarcadero\Studio\20.0\LabPacks\OpenWire Studio\Win64\;C:\Users\User\AppData\Local\Microsoft\WindowsApps; & “C:\Program Files\Unity\Hub\Editor\2019.3.1f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\build-tools\30.0.0-rc2\dx.bat” –dex –output=”D:\techy\delphiComponents\KastriFree-master\Demos\AndroidLocation\Application\Android64\Debug\LocationService-dexed.jar” “D:\techy\delphiComponents\KastriFree-master\Demos\AndroidLocation\Service\Android\Debug\LocationService.jar”” exited with code 1.
and here
procedure TfrmMain.LocationPermissionsResultHandler(Sender: TObject; const APermissions: TArray; const AGrantResults: TArray);
begin
if AGrantResults.AreAllGranted then
SendCommand(cServiceCommandResume);
end;
TArray does not contain a member name ‘AreAllGranted’ at line 199
Type of expression must be boolean.
What am I doing wrong here please.
The \core and \SDK folders don’t exist, and you should not need to add the \lib folder to the path anyway.
Unfortunately, that does not give enough information. Please check the Output tab of the Messages window when that error occurs, however I suspect it is to do with the SDK/NDK settings
If this is when compiling the AndroidLocation demo, then it seems you may have removed some code, specifically the function that starts on line 89 in the LA.MainFrm unit. Regardless, there’s a new demo that should be used now, which this article refers to: http://delphiworlds.com/2020/01/cross-platform-location-monitoring/
Hi Dave,
I try to compile AndroidLocation service demo but get error in unit LS.ServiceModule, it point to the line
constructor TServiceModule.Create(AOwner: TComponent);
begin
inherited;
FLocation := TLocation.Create;
FLocation.OnLocationChange := LocationChangeHandler; <— here
FConfig := TLocationConfig.GetConfig;
…
it says
[DCC Error] LS.ServiceModule.pas(196): E2009 Incompatible types: 'Parameter lists differ'
[DCC Error] LS.ServiceModule.pas(466): E2361 Cannot access private symbol TLocation.GetLastKnownLocation
[DCC Hint] LS.ServiceModule.pas(71): H2219 Private symbol 'PostRequest' declared but never used
[DCC Hint] LS.ServiceModule.pas(78): H2219 Private symbol 'SetIsPaused' declared but never used
[DCC Hint] LS.ServiceModule.pas(86): H2219 Private symbol 'SendNotification' declared but never used
[DCC Fatal Error] LocationService.dpr(5): F2063 Could not compile used unit 'LS.ServiceModule.pas'
could you help me what's wrong?
Thank you
Please use the updated demo from this article:
http://delphiworlds.com/2020/01/cross-platform-location-monitoring/
Thanks!
Thank you for the reply Dave,
but yes both article point to Kastrie Free on github, and I download it from there too. Open it from the Demos folder.
Thanks
Hi, Dave.
It would be great if you made a basic template for mobile services (working in the background, running after a reboot, cycling the task after a certain period of time), so you can use it for any task. For example, to update data in the database or parsing data from internet sites. What do I need to delete in this example to use it for other background tasks (not for location monitoring)?
The “ScheduledService” demo probably comes closest to your needs:
https://github.com/DelphiWorlds/KastriFree/tree/master/Demos/ScheduledService
Though it may need updating. Great suggestion, though 🙂
[…] I have written two articles on monitoring location changes: one for iOS, and one for Android. This article and the related demo brings everything up-to-date and merges support for both […]
hi Dave, congratulations for the great work in the kastri library,
I’m newcomer to Rad world, after to link all units I continus have a problem with the {$I DW.GlobalDefines.inc}.
I have incloud to the project, but the debugger is still wirting: [DCC Fatal Error] DW.FileWriter.pas(11): F1026 File not found: ‘DW.GlobalDefines.inc’
i’m actally working with last version, Delphi 10.4 Sydney
could u help me?
thanks.
As per the statement at the beginning of this article, you should be now referring to the updated article, i.e.: https://delphiworlds.com/2020/01/cross-platform-location-monitoring/
When compiling, if it cannot find DW.GlobalDefines.inc, you need to add the Include folder from the Kastri library to the project search path in the Project Options
HI Dave,
Thank you so much for this great library. Now my app is working well and capturing GPS coordinates even if I minimized my app. For now my question is it possible to capture every second I’m not sure the unit of MonitoringInterval is it in seconds or milliseconds. I tried the code below but not giving me coordinates every 1 second instead.
if FLocation = nil then
begin
FLocation := TLocation.Create;
FLocation.MonitoringInterval:= 1;
FLocation.NeedsBackgroundAccess := False;
FLocation.MinimumChangeInterval := 1;
FLocation.OnLocationChange := LocationChangeHandler;
FLocation.TimerTask.Schedule(1);
end;
What is the best to capture GPS location every 1 second.
Cheers!
Gerry,
Hi Gerry,
MonitoringInterval is in milliseconds, so I expect a value of 1 will be ignored. If using Fused Location API (which is the default in the demo, by way of a project conditional define), changing the interval may not have any effect (and is also not exact), and I may need to change the code to fix this.
Thank you Dave! I will wait for your update.