Location Service Extension
See the App Inventor Extensions document about how to use an App Inventor Extension.
For questions about this extension or bug reports please start a new thread in the
App Inventor community. Thank you.
For feature requests please contact me by email.
To be a sponsor of a new method already is possible starting from only 10 USD! With your contribution you will help the complete App Inventor community. Thank you.
Jan 12th, 2021: Version 1: initial version for App Inventor.
Jan 26th, 2021: Version 1a: new keyword URIENCODEDATETIME added
Jan 28th, 2021: Version 1b: new keyword URIENCODECURRENTADDRESS added, new method IsRunning added, properties now return the previously stored values after restarting the app
Jul 15th, 2022: Version 2: property 'Post' renamed to 'RequestText', new property 'RequestMethod' added, valid values are GET, POST, PUT, DELETE, PATCH, HEAD or OPTIONS,
new methods IsLocationBackgroundPermissionGranted and RequestLocationBackgroundPermission added. Thank you Lucas for being the sponsor of version 2.
Sep 27th, 2022: Version 3: SDK31 update: FLAG_IMMUTABLE for pending intents added, property MaxTimeBeforeShutdown in minutes added, RequestMethod helper added, bug fix for empty request header
Apr 7th, 2023: Version 3a: fused location provider replaced by gps to get precise location, automatic shutdown of service if gps is not available anymore
Apr 10th, 2023:
Version 3b: no automatic shutdown if GPS is not available anymore, another location provider will be used in this case, which might have worse accuracy
Description
Location Service Extension
This extension is able to run in the background while your app is closed and stores location data
(latitude, longitude and optionally current datetime, altitude, accuracy, speed, current address and provider) in TinyDB.
Also a background web functionality is available which can be used to send the location data to
a web service of your choice using a web request. This could be used for example to store the location data
in a MySQL database or to send an email after a location change was detected while the app is not running.
A notifier will be displayed while the location service is running in the background.
Thank you Marco for being the sponsor of this extension!
Minimum API level is 21 (Android 5).
Required permissions: android.permission.FOREGROUND_SERVICE, android.permission.ACCESS_FINE_LOCATION,
android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_BACKGROUND_LOCATION, android.permission.INTERNET
Kodular
As the UsesServices annotation meanwhile has been added into Kodular, this extension now also works in Kodular.
Properties


Determines the minimum time interval, in milliseconds, that the sensor will try
to use for sending out location updates. However, location updates will only be received
when the location of the phone actually changes, and use of the specified time interval
is not guaranteed. For example, if 1000 is used as the time interval, location updates will
never be fired sooner than 1000ms, but they may be fired anytime after.


Determines the minimum distance interval, in meters, that the sensor will try
to use for sending out location updates. For example, if this is set to 5, then the sensor will
fire a LocationChanged event only after 5 meters have been traversed. However, the sensor does
not guarantee that an update will be received at exactly the distance interval. It may take more
than 5 meters to fire an event, for instance.


Determines the maximum time in minutes before service will be shutdown automatically.
Default is 0, which means no automatic shutdown.


The tag for TinyDB which should be used to store the location data. The value will be a table in CSV format, which contains the location data, see options below.
After a trip the collected location data could be used for example to display in a map.
Optional location data to be stored in TinyDB
As the collected data can be extensive, the following properties can be used to decide, if a specific location information should be stored in TinyDB or not.


Specifies whether the current datetime should be provided as result in TinyDB.


Specifies whether coordinates (latitude and longitude) should be provided as result in TinyDB.


Specifies whether current address should be provided as result in TinyDB.


Specifies whether accuracy should be provided as result in TinyDB.


Specifies whether altitude should be provided as result in TinyDB.


Specifies whether speed should be provided as result in TinyDB.


Specifies whether provider should be provided as result in TinyDB.
Notification properties

The following 4 properties are used to configure the notification, which will be displayed while the location service is running in the background.


SmallIcon for notification. Recommended size is 96x96.


Title to be displayed in the notification.


Text to be displayed in the notification.


Text to be displayed in the shutdown button of the notifier. Default value is 'Shutdown'.
Background web properties
The following properties are used to configure the background web functionality to send a request.
The following requerst methods are available: GET, POST, PUT, DELETE, PATCH, HEAD and OPTIONS.
Also the background web functionality is able to convert keywords into their correponding values.
The following keywords are available: DATETIME, URIENCODEDATETIME, LATITUDE, LONGITUDE, ALTITUDE, ACCURACY, SPEED, CURRENTADDRESS, URIENCODECURRENTADDRESS and PROVIDER.
See the examples below how this can be used.


Specifies whether background web functionality should be enabled after a location changed event. Default Value is false.


The URL for the web request.


The method for the request. Valid values are GET, POST, PUT, DELETE, PATCH, HEAD or OPTIONS. Default value is 'POST'.
Note: in case an invalid value for RequestMethod is entered, the default value POST will be used.


The text for the web request.


The request headers, as a list of two-element sublists. The first element of each sublist
represents the request header field name. The second element of each sublist represents the request header field value.
Methods

Start Service.
Note: You will have to build the app to be able to start the service.

Returns true, if basic location permissions have been granted, else false.

Returns true, if background location permission has been granted, else false.

Request Basic Location Permission.
Note: You will have to build the app to be able to request location permission.

Request Background Location Permission.
Note: Starting with Android 12 asking the user to grant location permission got again more complicated,
see also this stackoverflow answer. The extension therefore offers 2 methods to ask for the required permissions.
Note: You will have to build the app to be able to request background location permission.
Android 6 to 9

The user needs to click "Allow" for the location service to be able to run.
Android 10

The user needs to click "Allow all the time" for the location service to be able to run in the background.
Android 11
On Android 11 (API level 30) and higher, however, the system dialog doesn't include the Allow all the time option anymore,
see also here. Instead, users must enable background location on the settings page.
The extension offers the method RequestBackgroundLocationPermmission for that.

Move task (i.e. the app) to the background.

Shutdown Service.
Note: You will have to build the app to be able to shutdown the service.

Returns true, if location service is running in the background, else false.
Events

Indicates that a new location has been detected. Speed is reported in meters/second.
Note: This event only will fire if the app is up and running.

Indicates that a web request has been executed in the background and a result is available.
Note: This event only will fire if the app is up and running.

Indicates that an Error occurred.

Indicates that service has been started.
Example blocks to send the location data to a MySQL database
while the location service is running in the background
For details how to use the web component to send data to a MySQL database,
see my MySQL project here. I used the following CREATE TABLE statement:
CREATE TABLE IF NOT EXISTS location(id VARCHAR(32), now DATETIME,
lat FLOAT,lng FLOAT, address varchar(255), PRIMARY KEY(id, now));
The web background functionality will convert the keywords into the correponding values. In the example
the keywords DATETIME, LATITUDE, LONGITUDE and CURRENTADDRESS will be replaced by the current location values.

INSERT INTO location VALUES("1234567", "2020-12-05 14:30:00", 51.5054597, -0.0775452, "Tower Bridge, London")

Note: You can use the Web.UriEncode method only for static values, not for dynamic values provided by the location service extension.
There are 2 values, which might need Uri encoding: DATETIME and CURRENTADDRESS, so if you need an Uri encoded DATETIME, use the keyword URIENCODEDATETIME rather than DATETIME and
if you need an Uri encoded CURRENTADDRESS, use the keyword URIENCODECURRENTADDRESS rather than CURRENTADDRESS.
The locations of last 5 user ids who used the example app
Id |
Datetime |
Latitude |
Longitude |
Address |
4207262 |
2023-01-13 04:39:00 |
37.7796 |
-122.392 |
No address available |
3480390 |
2023-01-06 16:34:05 |
-25.2864 |
-57.5731 |
PC7G CQJ, Asunción, Paraguay |
8414771 |
2022-10-04 01:17:03 |
37.0402 |
36.2255 |
FakıuÅaÄı, 45014 Sk No: 46/1, 80000 Osmaniye Merkez/Osmaniye, Türkiye |
1476450 |
2022-09-28 00:07:15 |
53.3498 |
-6.2603 |
No address available |
2886032 |
2022-09-08 20:32:24 |
-7.36098 |
112.647 |
Jl. Raya Bambe No.215, Sarirejo, Bambe, Kec. Driyorejo, Kabupaten Gresik, Jawa Timur 61177, Indonesia |
Example blocks to send an Email
while the location service is running in the background
For the Email example I'm using the IFTTT solution, which is described here.
The web background functionality again will convert the key words into the correponding values.
In IFTTT there are 3 variables called VALUE1, VALUE2 and VALUE3 to define:
I used VALUE1 as the receiver email address and VALUE2 and VALUE3 are being displayed in the body of the message.

Example Email
Example App "Locationservice Test"
Example app to send location data to a Google Spreadsheet
while the location service is running in the background
This example is based on the Google Spreadsheet example by TimAI2, Thank you Tim! First try the solution by Tim.
After you get this running, then use my Spreadsheet example project, add your script url and try it. For easier testing
use the ErrorOccured event and GotText event of the locationservice extension to find out, if the script has been setup correctly and receives the data correctly.
After you get this running, then adjust it to your needs.
For your own project make sure, the property ShowListsAsJson is checked in the properties of Screen1.


Test
Version 1 tested successfully on Samsung Galaxy A5 running Android 8 and Galaxy A51 running Android 10.
I also tested on the following emulators: Nexus 5 running Andrid 5, Nexus 6 running Android 6,
Nexus 5X running Android 8 and Xiaomi Redmi Note 7 running Android 9. Version 2 and 3 tested successfully on Samsung Galaxy A51 running Android 12.
Questions and Answers
Q1: Tips for getting your app approved for background location access
A: See this Google Blog, see also the Google Policy chapter Location Permissions.
Q2: I'm using the following request header and somehow the web background functionality does not work?

A: Please use the ErrorOccurred event to find out, if the defined request header is correct. In your case the following error message will be displayed:
Invalid value for RequestHeaders property. This must be a list of sublists. Each sublist must have a key and a value.
Q3: Do I need the Move Task To Back function in order to start the tracing or can the user simply press the O button (go to the home screen of his phone) to start another app?
A: The service starts as soon as the StartService method is executed, this is not dependent on sending the app to the back.
Yes, the user also can press the Home button of the device to start another app.
Q4: I need to send latitude and longitude to firebase database in background. How can I do this with your extension?
A: Yes you can. See this tutorial by TimAI2 how to send data to your Firebase database using the web component. Thank you Tim!
After you are successfully able to use the web component to send data to your firebase database,
then accordingly set up the background web functionality of the locationservice extension.
Q5: Do you help me for send simples coordinates (latitude, longitude)?

A: The blocks look fine assuming, you first do the setup and then start the service.
To find out, if these blocks are the correct ones which work together with your server, follow these 3 steps:
Step 1: prepare some test blocks which use the web component together with your server url and check,
if the test data is received on the server. Also check, which result you get in the Web.GotText event... You can use the companion app for the first step.
A good server script will return some kind of success message or error message.

Step 2: Then setup the background feature of the extension. Some examples of a successful setup see above: a) MySQL, b) IFTTT mail example, c) Google Spreadsheet.
After defining the different parameter for your purposes start the service. Now build your app and start testing while the app is up and running.
Move around to get a location and use the GotText event of the TaifunLocationService extension to display the result in a label. Check the result and compare it with the result from step 1.
A good server script will return some kind of success message or error message.
Also check if the LocationChanged event triggered. If it did not trigger, then you did not move around to get a location. And use the ErrorOccurred event to find out, if any error occurred.

Step 3: If both steps have been successful, then test again while the app is running in the background.
Test the functionality of the Location Service extension
The test app is available in Google Play. You can test the extension following these steps
- Read and agree to the Privacy Policy.
- Follow the opt-in URL for the locationservice example app
to get access to the app and to be able to download it to your device. Here you can test all the features.
- Start testing.
Buy the Location Service extension for
App Inventor